よく忘れるのでメモ。
一定のサイズごとに分ける
>>> a = range(20) >>> n = 5 >>> zip(*[iter(a)]*n) [(0, 1, 2, 3, 4), (5, 6, 7, 8, 9), (10, 11, 12, 13, 14), (15, 16, 17, 18, 19)]
個数が割り切れない場合は、切り捨てられるので注意。
>>> a = range(22) >>> zip(*[iter(a)]*n) [(0, 1, 2, 3, 4), (5, 6, 7, 8, 9), (10, 11, 12, 13, 14), (15, 16, 17, 18, 19)]
切り捨てないで分けるには、やや煩雑ではあるが次のようにする。
>>> [a[n*i:n*(i+1)] for i in xrange(len(a)/n+1)] [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12, 13, 14], [15, 16, 17, 18, 19], [20, 21]] >>> map(lambda *x: filter(lambda x: x is not None, x), *[iter(a)]*n) [(0, 1, 2, 3, 4), (5, 6, 7, 8, 9), (10, 11, 12, 13, 14), (15, 16, 17, 18, 19), (20, 21)]
2次元配列の転置
>>> a = [range(4) for i in range(4)] >>> a [[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]] >>> map(list, zip(*a)) [[0, 0, 0, 0], [1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3]]
個数が合わない場合は、やはり切り捨てられるので注意。
>>> a = [range(2), range(3), range(4)] >>> a [[0, 1], [0, 1, 2], [0, 1, 2, 3]] >>> map(list, zip(*a)) [[0, 0, 0], [1, 1, 1]]
2次元配列の1次元化
sum()
は第2引数に初期値を与えることができ、明示的に空リストを指定することでサブリストの結合ができる。
>>> a = [range(4) for i in range(4)] >>> a [[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]] >>> sum(a, []) [0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3]
あるいは、itertools.chain()
を使う。
>>> import itertools >>> list(itertools.chain(*a)) [0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3]
最も長い文字列を選ぶ
list.sort()
やsorted()
と同様に、max()
もキーワード引数として比較キーを計算する関数を与えることができ、len()
を指定することで文字列長などが最も長い要素を1個選ぶことができる。
>>> a = "hello nice to meet you".split() >>> a ['hello', 'nice', 'to', 'meet', 'you'] >>> max(a, key=len) 'hello'
min()
についても同じである。
>>> min(a, key=len) 'to'
二つの配列の直積
あまりトリッキーではないけどついでに。
>>> a = range(2) >>> b = range(3) >>> [(i,j) for i in a for j in b] [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)]
あるいは、itertools.product()
を使う。
>>> import itertools >>> list(itertools.product(a,b)) [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)]