サイトアイコン Python Snippets

各種リテラルと内包表記について

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))
関連記事:

モバイルバージョンを終了