3.1での変更点とか

しばらく追いかけてなかった。ので、久々に追いかけて覚書。

PEP 372: 順序付き辞書

rubyでも1.9からこっちになって、しかしあんまり利点がわかってなかったんだけど、例えばconfigファイルとかでパースして利用して、それを読み込んだ順でそのまま保存できたりする、とか便利なのだね。

>>> from collections import OrderedDict
>>> data = [tuple(elm.split(':')) for elm in "one:1,two:2,three:3,four:4".split(',')]
>>> raw_dict  = dict(data)
>>> ord_dict  = OrderedDict(data)
>>> for key,value in raw_dict.items(): print (key)
... 
four
three
two
one
>>> for key,value in ord_dict.items(): print (key)
... 
one
two
three
four

どうやってるのかと思ったんだけど単純に

class OrderedDict(dict, MutableMapping):
  :
    def __setitem__(self, key, value):
        'od.__setitem__(i, y) <==> od[i]=y'
        # Setting a new item creates a new link which goes at the end of the linked
        # list, and the inherited dictionary is updated with the new key/value pair.
        if key not in self:
            self.__map[key] = link = _Link()
            root = self.__root
            last = root.prev
            link.prev, link.next, link.key = last, root, key
            last.next = root.prev = _proxy(link)
        dict.__setitem__(self, key, value)

リンクこさえてるだけだった。遅そう。とか思ったけど頻繁に書き換え(__setitem__()呼ば)なければ関係ないか。

PEP 378: 数字を1000ごとに','で区切る

thousands separatorとな。

>>> format(1231231,",d")
'1,231,231'

便利なのかな。自分で作るの嫌だし。

>>> def thousep(s):
...  l = len(s)
...  ret = [s[0:l%3]] if l%3 else []
...  return ",".join(ret+[s[i:i+3] for i in range(l%3, l, 3)])
... 
>>> thousep("100030")
'100,030'
>>> thousep("10030")
'10,030'
>>> thousep("1000")
'1,000'

NAんとダサい。しかも py3限定。

その他

bit_length()
>>> n = 123456
>>> bin(n)
'0b11110001001000000'
>>> n.bit_length()
17

うわあ、なんか変態的。誰が使うんだ誰が。

format stringに番号がいらなくなった。
>>> "number {} not {}".format('is now', 'needed')
'number is now not needed'

ちと楽になった(前は {0}, {1}のように番号が必須だった)。けど間違いメーカーかも。

string.maketrans() -> bytes.maketrans()

わかりやすいように整理・お引越し。

複数コンテキストのwith
with open("filea") as filea, open("fileb") as fileb:
  :
  :

nestedいらなくなってdeprecatedになった。

floatの表示方法

浮動小数点数の表示アルゴリズムが David Gayのアルゴリズムとやらに変わったらしい。時間があったら後で調べてみよう。

Python 2.6.1 (r261:67515, Feb  4 2009, 21:18:23) 
[GCC 4.2.4 (Ubuntu 4.2.4-1ubuntu3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> float('1.1')
1.1000000000000001
>>> float('1.1')-1
0.10000000000000009
>>> float('1.1')-0.1
1.0
>>> float('0.1')
0.10000000000000001
>>> 
quartz% python3.1
Python 3.1rc2 (r31rc2:73411, Jun 17 2009, 13:40:30) 
[GCC 4.2.4 (Ubuntu 4.2.4-1ubuntu3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> float(1.1)
1.1
>>> float(1.1)-0.1
1.0
>>> float(0.1)
0.1

ふうん。

モジュール関連

Counter

というよりHistogramだよね

>>> Counter([random.randint(0,16) for i in range(10000)])
Counter({1: 621, 0: 619, 2: 612, 7: 611, 14: 602, 13: 594, 11: 593, 9: 591, 15: 589, 3: 588, 4: 582, 16: 580, 8: 579, 10: 579, 12: 563, 5: 556, 6: 541})
gzip, bz2

おお楽チン

>>> with bz2.BZ2File("foo.bz2", "wb") as out:
...   out.write(b"hogerimakurimakuri")
... 
zsh: suspended  python3.1
quartz% bzcat foo.bz2
hogerimakurimakuri
quartz% 
itertools

combinations_with_replacement() が、、、って馬鹿みたいに喜んで前にやった奴 http://d.hatena.ne.jp/tkuro/20090309/1236632505
やってしまった。

>>> ["".join(x) for x in itertools.combinations_with_replacement('EARTH', 5)]
['EEEEE', 'EEEEA', 'EEEER', 'EEEET', 'EEEEH', 'EEEAA', 'EEEAR', 'EEEAT', 'EEEAH', 'EEERR', 'EEERT', 'EEERH', 'EEETT', 'EEETH', 'EEEHH', 'EEAAA', 'EEAAR', 'EEAAT', 'EEAAH', 'EEARR', 'EEART', 'EEARH', 'EEATT', 'EEATH', 'EEAHH', 'EERRR', 'EERRT', 'EERRH', 'EERTT', 'EERTH', 'EERHH', 'EETTT', 'EETTH', 'EETHH', 'EEHHH', 'EAAAA', 'EAAAR', 'EAAAT', 'EAAAH', 'EAARR', 'EAART', 'EAARH', 'EAATT', 'EAATH', 'EAAHH', 'EARRR', 'EARRT', 'EARRH', 'EARTT', 'EARTH', 'EARHH', 'EATTT', 'EATTH', 'EATHH', 'EAHHH', 'ERRRR', 'ERRRT', 'ERRRH', 'ERRTT', 'ERRTH', 'ERRHH', 'ERTTT', 'ERTTH', 'ERTHH', 'ERHHH', 'ETTTT', 'ETTTH', 'ETTHH', 'ETHHH', 'EHHHH', 'AAAAA', 'AAAAR', 'AAAAT', 'AAAAH', 'AAARR', 'AAART', 'AAARH', 'AAATT', 'AAATH', 'AAAHH', 'AARRR', 'AARRT', 'AARRH', 'AARTT', 'AARTH', 'AARHH', 'AATTT', 'AATTH', 'AATHH', 'AAHHH', 'ARRRR', 'ARRRT', 'ARRRH', 'ARRTT', 'ARRTH', 'ARRHH', 'ARTTT', 'ARTTH', 'ARTHH', 'ARHHH', 'ATTTT', 'ATTTH', 'ATTHH', 'ATHHH', 'AHHHH', 'RRRRR', 'RRRRT', 'RRRRH', 'RRRTT', 'RRRTH', 'RRRHH', 'RRTTT', 'RRTTH', 'RRTHH', 'RRHHH', 'RTTTT', 'RTTTH', 'RTTHH', 'RTHHH', 'RHHHH', 'TTTTT', 'TTTTH', 'TTTHH', 'TTHHH', 'THHHH', 'HHHHH']

違うよ permutationじゃないってば。だめだめ。(<バカ)
それはこっちだ。

>>> ["".join(x) for x in itertools.permutations('AEHRT')]
['AEHRT', 'AEHTR', 'AERHT', 'AERTH', 'AETHR', 'AETRH', 'AHERT', 'AHETR', 'AHRET', 'AHRTE', 'AHTER', 'AHTRE', 'AREHT', 'ARETH', 'ARHET', 'ARHTE', 'ARTEH', 'ARTHE', 'ATEHR', 'ATERH', 'ATHER', 'ATHRE', 'ATREH', 'ATRHE', 'EAHRT', 'EAHTR', 'EARHT', 'EARTH', 'EATHR', 'EATRH', 'EHART', 'EHATR', 'EHRAT', 'EHRTA', 'EHTAR', 'EHTRA', 'ERAHT', 'ERATH', 'ERHAT', 'ERHTA', 'ERTAH', 'ERTHA', 'ETAHR', 'ETARH', 'ETHAR', 'ETHRA', 'ETRAH', 'ETRHA', 'HAERT', 'HAETR', 'HARET', 'HARTE', 'HATER', 'HATRE', 'HEART', 'HEATR', 'HERAT', 'HERTA', 'HETAR', 'HETRA', 'HRAET', 'HRATE', 'HREAT', 'HRETA', 'HRTAE', 'HRTEA', 'HTAER', 'HTARE', 'HTEAR', 'HTERA', 'HTRAE', 'HTREA', 'RAEHT', 'RAETH', 'RAHET', 'RAHTE', 'RATEH', 'RATHE', 'REAHT', 'REATH', 'REHAT', 'REHTA', 'RETAH', 'RETHA', 'RHAET', 'RHATE', 'RHEAT', 'RHETA', 'RHTAE', 'RHTEA', 'RTAEH', 'RTAHE', 'RTEAH', 'RTEHA', 'RTHAE', 'RTHEA', 'TAEHR', 'TAERH', 'TAHER', 'TAHRE', 'TAREH', 'TARHE', 'TEAHR', 'TEARH', 'TEHAR', 'TEHRA', 'TERAH', 'TERHA', 'THAER', 'THARE', 'THEAR', 'THERA', 'THRAE', 'THREA', 'TRAEH', 'TRAHE', 'TREAH', 'TREHA', 'TRHAE', 'TRHEA']
>>> ["".join(x) for x in itertools.permutations('AEHRT')][54]
'HEART'