Pythonのリスト内包表記はよく知られていますが、その他のオブジェクトについても内包表記と、直接記述する場合のリテラルについてまとめます。
※Python3で導入された表記がPython2.7でも使えるようになっています。
リスト(list)
よく知られたリスト内包表記です。
l1 = [0, 2, 4, 6, 8] # listリテラル
l2 = [x*2 for x in range(5)] # list内包表記
print l1, l2
# -> [0, 2, 4, 6, 8] [0, 2, 4, 6, 8]
タプル(tuple)
タプルは内包表記がありません。一見、()で書ける内包表記があるようですがこれはジェネレータ式です。
t1 = (0, 2, 4, 6, 8) # tupleリテラル
t2 = tuple(x*2 for x in range(5)) # tuple内包表記はない。ジェネレータ式でtuple関数に渡す
print t1, t2
# -> (0, 2, 4, 6, 8) (0, 2, 4, 6, 8)
(x*2 for x in range(5))
というのはtuple内包表記ではなくgeneratorを返す式。これをtuple関数に渡すときに tuple((for x*2 in x in range(5)))
と書け、
この場合の括弧は省略できて tuple(x*2 for x in range(5))
という表記になる。
集合/セット (set)
setの場合はPython2.7からsetリテラルと内包表記が導入された。
s1 = {0, 2, 4, 6, 8} # setリテラル (ver2.7以降)
s2 = {x*2 for x in range(5)} # set内包表記(ver2.7以降)
print s1, s2
# -> set([0, 8, 2, 4, 6]) set([0, 8, 2, 4, 6])
Python2.6では、リテラルの代わりに set([0,2,4,6,8])
とリストで作ってset関数へ渡したり、内包表記の代わりに set(x*2 for x in range(5))
のようにジェネレータをset関数へ渡す。
dict内包表記と似ているので注意。特に要素数ゼロのsetはリテラルで記述できない
print type({1}), type({}) #要素数0のsetをリテラルで記述しようとするとdictになる!
# -> <type 'set'> <type 'dict'>
辞書/ディクショナリ (dict)
dictはPython2.7からdict内包表記が使える。
d1 = {0:0, 1:2, 2:4, 3:6, 4:8} # dictリテラル
d2 = {x:x*2 for x in range(5)} # dict内包表記(ver2.7以降)
print d1, d2
# -> {0: 0, 1: 2, 2: 4, 3: 6, 4: 8} {0: 0, 1: 2, 2: 4, 3: 6, 4: 8}
Python2.6では、内包表記の代わりに dict((x, x*2) for x in range(5))
のようにジェネレータをdict関数へ渡す。
ジェネレータ式(generator)
内包表記やリテラルとは関係ないが、内包表記と記述が似ているのでジェネレータ式も記載する。
def gen_func():
#ジェネレータを返す関数
for x in range(5):
yield x*2
g1 = gen_func()
g2 = (x*2 for x in range(5)) #ジェネレータ式
print g1, g2
# -> <generator object.... >, <generator object.... >
print sum(g1), sum(g2)
# -> 20 20
イテレータとして振る舞うジェネレータを返すのがジェネレータ式。リストのようにメモリ中に全要素を格納せず、次の要素を順番に生成する。
まとめ
データ型 | リテラル | 内包表記(or 代替) |
---|---|---|
リスト(list) | [0,2,4] | [x*2 for x in range(3)] |
タプル(tuple) | (0,2,4) | tuple(x*2 for x in range(3)) |
セット(set) | {0,2,4} # 2.7 set([0,2,4]) # 2.6 |
{x*2 for x in range(3)} # 2.7 set(x*2 for x in range(3)) # 2.6 |
ディクショナリ(dict) | {0:0, 1:2, 2:4} | {x:x*2 for x in range(3)} # 2.7 dict((x,x*2) for x in range(3)) # 2.6 |
ジェネレータ式 | – | (x*2 for x in range(3)) |