pythonでは ret = [x ** 2 for x inlst]
の形式の割り当てステートメントがよく見られます。C++からpythonに切り替える人にとって、このforループの使用法を理解するのは簡単ではありません。これはpythonです。簡潔にするために発明された新しい構文。 Python分析式には、次の利点があります。
Pythonの分析式は、次の4つのタイプに分けられます。
以下では、これら4つの分析式の使用について説明します。
包括的なフォームを一覧表示
[ expr for e in iterator]
In [1]: lst =range(10)
In [2]:%%timeit
...: ret =[x **2for x in lst]...:100000 loops, best of3:5.28 µs per loop
In [3]:%%timeit
...: ret =[]...:for x in lst:...: ret.append(x **2)...:100000 loops, best of3:6.09 µs per loop #少し時間がかかる
効率がわずかに高いことがわかります。最も重要なことは、コードの単純さです。
リスト内包表記は if
ステートメントで使用できます
たとえば、リスト lst
の偶数を除外します。
In [4]: ret =[]
In [5]:for x in lst:...:if x %2==0:...: ret.append(x) #forループを使用
...:
In [6]: ret
Out[6]:[0,2,4,6,8]
In [7]: ret =[x for x in lst if x %2==0] #リスト内包表記を使用する
In [8]: ret
Out[8]:[0,2,4,6,8]
リスト内包表記では、 for
ループのような if
ステートメントを使用できます。
リストの包括的な for
ステートメントはネストできます。
In [9]:(x, y)for x inrange(0,5)for y inrange(5,10)
File "<ipython-input-9-825e2443da8b>", line 1(x, y)for x inrange(0,5)for y inrange(5,10)^
SyntaxError: invalid syntax
# リスト内包表記は角括弧で囲む必要があることを説明します
In [10]:[(x, y)for x inrange(5)for y inrange(5,10)]
Out[10]:[(0,5),(0,6),(0,7),(0,8),(0,9),(1,5),(1,6),(1,7),(1,8),(1,9),(2,5),(2,6),(2,7),(2,8),(2,9),(3,5),(3,6),(3,7),(3,8),(3,9),(4,5),(4,6),(4,7),(4,8),(4,9)]
In [11]: ret =[]
In [12]:for x inrange(5):...:for y inrange(5,10):...: ret.append((x, y))...:
In [13]: ret
Out[13]:[(0,5),(0,6),(0,7),(0,8),(0,9),(1,5),(1,6),(1,7),(1,8),(1,9),(2,5),(2,6),(2,7),(2,8),(2,9),(3,5),(3,6),(3,7),(3,8),(3,9),(4,5),(4,6),(4,7),(4,8),(4,9)]
if
ステートメントの特別な使用法
単一行のifステートメントは、リスト内包表記と非常によく似ています。
式の形式: x if cond else y
if
と else
は同時に存在する必要があります。
例として、偶数を2乗し、奇数を3乗してみましょう。
In [14]: ret =[]
In [15]:for x in lst:...:if x %2==0:...: ret.append(x **2)...:else:...: ret.append(x **3)...:
In [16]: ret
Out[16]:[0,1,4,27,16,125,36,343,64,729]
In [17]: x =3
# 特別な使用法の場合
In [18]: x **2if x %2==0else x **3
Out[18]:27
In [19]:3if True else4
Out[19]:3
# if with list comprehension x if cond else yforの特別な使用法...
In [20]:[x **2if x %2==0else x **3for x in lst]
Out[20]:[0,1,4,27,16,125,36,343,64,729]
リスト内包表記はリストを返し、ジェネレーター内包表記は解析を返します。リスト内包表記の括弧は括弧になります。これはジェネレーターの解析です。
In [1]:range(10000)
Out[1]:range(0,10000)
In [2]: g =(x **2for x inrange(100000000000))
In [3]: g
Out[3]:<generator object <genexpr> at 0x7f9f08a5f0a0>
In [4]:next(g)
Out[4]:0
In [5]:next(g)
Out[5]:1
In [6]:next(g)
Out[6]:4
リスト内包表記とジェネレーター内包表記の選択
リスト内包表記の四角い括弧を中括弧で置き換えることは、セット内包表記です。
In [1]: lst =[2,4,5,6,3,4,2]
In [2]: s ={x for x in lst}
In [3]: s
Out[3]:{2,3,4,5,6} #収集要件を満たすリスト内包表記が生成されると、繰り返しが削除されることがわかります。
In [4]:type(s)
Out[4]:set
辞書分析でも中括弧を使用しますが、セット分析とは異なり、単一の要素ではなく、 expr
で k、v
のペアを使用します。
In [1]:{str(x): x for x inrange(5)}
Out[1]:{'0':0,'1':1,'2':2,'3':3,'4':4}
4つの分析式の中で最も広く使用されているのはリスト内包表記であり、多くの場合、いくつかの巧妙な使用法があります。
Recommended Posts