pythonサイクル高度用法[expression for x in X[if condition]for y in Y[if condition]...for n in N[if con

6341 ワード

http://www.cnblogs.com/bonelee/p/8545263.html
高度な構文
上記の[x ** 2 for x in L]のような基本構文に加えて、リスト導出式にはいくつかの高度な拡張子があります.
4.1.if文付きfor文の後にif判定文を追加して、条件を満たさない結果アイテムをフィルタリングすることができます.
たとえば、リスト内のすべての偶数を除去し、奇数を保持したい場合は、次のように書きます.
>>> L = [1, 2, 3, 4, 5, 6]
>>> L = [x for x in L if x % 2 != 0]
>>> L
[1, 3, 5]

4.2 forネスト付き
複雑な点のリスト導出式では、for文を複数ネストすることができる.左から右の順に、それぞれ外層サイクルから内層サイクルである.
例:
>>> [x + y for x in 'ab' for y in 'jk']
['aj', 'ak', 'bj', 'bk']

4.3.if文とforネストがある
リスト導出式は、任意の数のネストされたforサイクルを有することができ、各forサイクルの後には、オプションのif文がある.
一般的な構文:
[ expression for x in X [if condition]
             for y in Y [if condition]
             ...
             for n in N [if condition] ]

例えば、以下のコードは、0~4の間の偶数と奇数の組み合わせを出力する.
>>> [(x, y) for x in range(5) if x % 2 == 0 for y in range(5) if y % 2 == 1]
[(0, 1), (0, 3), (2, 1), (2, 3), (4, 1), (4, 3)]

次の一般的なforサイクルに等価です.
>>> L = []
>>> for x in range(5):
...     if x % 2 == 0:
...         for y in range(5):
...             if y % 2 == 1:
...                 L.append((x, y))
>>> L
[(0, 1), (0, 3), (2, 1), (2, 3), (4, 1), (4, 3)]

4.4.リスト導出式生成マトリックス
マトリクスを生成する方法は、手動付与、一般的なforループ、およびリスト導出式など、いくつかあります.リスト導出式で次のマトリクスを生成する場合は、どう書きますか?
>>> M = [[1, 2, 3],
... [4, 5, 6],
... [7, 8, 9]]

1つの方法は次のとおりです.
>>> M = [[x, x+1, x+2] for x in [1, 4, 7]]
>>> M
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

この方法は,行列の列数が少ない場合に用いることができる.
行列の列数が多い場合は、ループ変数の式でリスト導出式を使用する別の方法を使用できます.
具体的なコードは以下の通りです.
>>> M = [[y for y in range(x, x+3)] for x in [1, 4, 7]]
>>> M
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

以前のforネストされた構文とは異なり、この例では最も基本的な[expression for x in L]構文が使用され、for文が1つしかありません.
複雑な点は、前述の変数式expressionが単純な変数演算ではなく、リスト導出式であり、この例では[y for y in range(x, x+3)]である.内層のリスト導出式は1つの行ベクトルを返し、これらの行ベクトルは外層のリスト導出式を経て、最終的に2次元リスト、すなわち私たちが望む行列を形成する.
もちろん,実際の応用では単純にコードの簡潔さを追求するのではなく,コードの可読性とメンテナンスコストも考慮する.コードが複雑になりすぎて理解しにくい場合は、コードを何行も書いて可読性を高めたほうがいいです.
5.ジェネレータ式
ジェネレータ式は、ジェネレータ式の外側に括弧を使用し、リスト式に角括弧を使用するのと同じ構文です.
ジェネレータについては、この記事を参照してください.「Python高度なプログラミングの初心者ジェネレータ」
6.集合導出式と辞書導出式
注意:集合導出式と辞書導出式はPython 2.7以降のバージョンにのみ存在し、Python 2.7以前のバージョンではこの2つの導出式はサポートされていません.
集合導出式の構文はリスト導出式と同様で,外の角括弧を花括弧に変更するだけでよい.
たとえば、次の方法でコレクションを生成できます.
>>> {x ** 2 for x in [1, 2, 2]}
{1, 4}

辞書の導出式の外側もカッコを使用しますが、カッコの内部にはキー値の2つの部分が含まれている必要があります.
値が重複しない場合は、辞書でキー値ペアをすばやく交換できます.
>>> D = {'a':1, 'b':2, 'c':3}
>>> D = {value: key for key, value in D.items()}
>>> D
{1: 'a', 2: 'b', 3: 'c'}

from:http://www.codebelief.com/article/2017/02/python-advanced-programming-list-comprehensions/
 
lix = [];
for x in range(1, 101):
    lix.push(x ** 2)
    :lix = [1,4,9,16,25.....]

リストビルダーの式では、簡単な条件処理を追加できます.
lix = [x * x for x in range(1, 101) if x % 2 == 0]
    :lix = [4,16,36.....]

また、ループ中に多層ループネストを使用して、より複雑な効果を実現することもできます.
lix = [x + y  for x in "abc" for y in "xyz"]
    :['ax', 'ay', 'az', 'bx', 'by', 'bz', 'cx', 'cy', 'cz']

リストダイナミックビルダー
しかし、私たちは前の学習を通じて、これらのデータはすべてメモリにロードされていることを知っています.リストのデータ量が大きい場合、メモリ消費が深刻です.場合によっては、リストの一部のデータを使用するだけです.後のデータは特に関心を持っていません.例えば、リストを通じてルールに合ったシーケンスを記録します.毎回私たちは次のデータに関心を持っているだけで、後ろのN本のデータに関心を持っていません.どうすればいいですか.例えば奇数リストが必要です
#         
lix = [2*x + 1 for x in range(1, 101)]
#     :[1,3,5,7,9,11,13,15,17.....]
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
#              
#       ,            ,       
#            ,        10 
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
#          
lix = (2 * x - 1 for x in range(1, 101))
#     :print (lix) -->  at 0x7f232e462048>
next(lix)
#     :1
next(lix)
#     :3
next(lix)
#     :5
next(lix)
#     :7
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
#        
#           ,              
#     next()              
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

from:https://www.jianshu.com/p/fa3fda487f15
 
 
[]()に変更すると、generatorが作成されます.
>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
 at 0x1022ef630>

Lとgの違いは、最外層の[]()Lがlistであり、gがgeneratorであることにすぎない.
1つずつ印刷する場合は、generatorの次の戻り値をnext()関数で取得できます.
>>> next(g)
0
>>> next(g)
1
>>> next(g)
4
>>> next(g)
9
>>> next(g)

next(g)は本当に変態で、generatorも反復可能なオブジェクトであるため、正しい方法はforサイクルを使用することです.
>>> g = (x * x for x in range(10))
>>> for n in g:
...     print(n)
... 
0
1
4
9
  fib    generator,    print(b)  yield b
def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return 'done'
 

yieldキーワードでは、この関数は普通の関数ではなくgeneratorです.
 
>>> f = fib(6)
>>> f

 

return文または最後の行の関数文が返されます.generatorとなる関数は、next()が呼び出されるたびに実行され、yield文の戻りに遭遇し、再実行時に前回返されたyield文から実行が継続される.