Remrinのpython攻略日記

python3に入門しました。python3についてあれこれとサンプルコードとか。

内包表記

内包表記(comprehension)の使い方。
 
map()やfilter()に近い使い方を高速に実行できる表記方法。

l2 = [x*2 for x in range(4)]   # リスト内包表記  [0, 2, 4, 6]
g  = (x*2 for x in range(4))   # ジェネレータ式  0, 2, 4,...
d2 = {x:x*2 for x in range(4)} # dict内包表記    {0:0, 1:2, 3:6}
s2 = {x*2 for x in range(4)}   # set内包表記     {0, 2, 4, 6}

 

map()に似た使い方

list1 = map(lambda x:x**2, range(5))
print(type(list1))  # <class 'map'>
#print(len(list1))  # TypeError: object of type 'map' has no len()
print(list(list1))  # [0, 1, 4, 9, 16]

 
上記のコードをリスト内包表記を使って書くと

list1 = [i**2 for i in range(5)]
print(type(list1))  # <class 'list'>
print(len(list1))   # 5
print(list1)        # [0, 1, 4, 9, 16]

 

filterに似た使い方

list1 = filter(lambda i:i%2 == 1, range(5))
print(type(list1))  # <class 'filter'>
#print(len(list1))  # object of type 'filter' has no len() 
print(list(list1))  # [1, 3]

 
上記のコードを内包表記を使って書くと

list1 = [i for i in range(5) if i%2 == 1]
print(type(list1))  # <class 'list'>
print(len(list1))   # 2
print(list1)        # [1, 3]

 

map() + filter()に似た使い方

list1 = [i**2 for i in range(5) if i%2 == 1]
print(list1)        # [1, 9]

 

forのネスト

list1 = []
for x in [0, 10, 20]:
    for y in range(3):
        list1.append(x+y)
print(list1)  # [0, 1, 2, 10, 11, 12, 20, 21, 22]

 
これをリスト内包表記で書くと

list1 =[x+y for x in [0, 10, 20] for y in range(3)]
print(list1)  #[0, 1, 2, 10, 11, 12, 20, 21, 22]

 

内包表記の利用例

・1, 2, 3から2つ並べる順列(permutation)

list1 = [(x, y) for x in [1, 2, 3] for y in [1, 2, 3] if x!=y]
print(list1)  # [(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]

 
・1,2,3から2つ選ぶ組み合わせ(combination)

list1 = [(x, y) for x in [1, 2, 3] for y in [1, 2, 3] if x<y]
print(list1)  # [(1, 2), (1, 3), (2, 3)]

 
・行列の次数下げ(flatten)

matrix = [[1,2,3], [4,5,6], [7,8,9]]
list1 = [num for row in matrix for num in row]
print(list1) # [1, 2, 3, 4, 5, 6, 7, 8, 9]

 
・2つのリストの操作

list1 = [1, 2, 3]
list2 = [4, 5, 6]
print([x * y for x in list1 for y in list2])    # [4, 5, 6, 8, 10, 12, 12, 15, 18]
print([list1[i] * list2[i] for i in range(3)])  # [4, 10, 18]
print([i*j for (i,j) in zip(list1, list2)])     # [4, 10, 18]

 
・かけ算九九の表

list1 = [[x * y for y in range(1,10)]  for x in range(1,10)]
print(list1)
# [[1, 2, 3, 4, 5, 6, 7, 8, 9], [2, 4, 6, 8, 10, 12, 14, 16, 18],…

 
・ネストしている内側を操作

list1 = [[y * 2 for y in x] for x in [[1,2],[2,3]]]
print(list1) # [[2, 4], [4, 6]]

 
・行列の転置(transpose)

maps = [[1, 2], [3, 4], [5, 6]]
transposed = [[row[i] for row in maps] for i in range(len(maps[0]))]
print(transposed)  # [[1, 3, 5], [2, 4, 6]]

 
・コドン表を作る

bases = "UCAG"
codons = [b1+b2+b3 for b1 in bases for b2 in bases for b3 in bases]
aminoacids = "FFLLSSSSYY**CC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG"
codon_dict = dict(zip(codons, aminoacids))
print(codon_dict)
# {'UCA': 'S', 'AUC': 'I', 'GAC': 'D', 'ACA': 'T', ...