python docs on Expressions を見てください。これらはすべて、さまざまな複雑さの、何らかの種類の値を表すだけのものです。それらは、副作用を誘発するもの (I/O など) や可変データの変換ではありません。ジェネレーター式は、その名前が示すように、単なる別の種類の式です。
コード行を減らすことは、ジェネレーター式の本来の目的ではありません。「メモリ効率と遅延計算された値」(以下のコメンターに感謝) の主な有用性を超えて、それらの目的の大部分は、イテレータをよりアクセスしやすい種類の原子値にすることで、コードをより簡潔で読みやすくすることです。コードの可読性を低下させている場合は、ジェネレーター式の使用が間違っている可能性があります。
特にジェネレータ式は、Python プログラミングの関数型パラダイムと密接に結びついているように思えます。例のように、数学的に定義されたシリーズから期待される値が得られますthe generator yielding all the Fibonacci numbers
。この機能的パラダイムを念頭に置いて、特に副作用を生成するためにジェネレーターを使用することは、おそらくコードの匂いです。
ジェネレータ式を使用する正しい方法は、反復可能なデータセットの 1 つの要素に対して一度に 1 つの明確に定義された変換を実行し、後でその変換されたデータを生成することです。これは、関数パラダイムに適合します。つまり、関数は値を受け取り、値を返し、副作用はありません。
ジェネレーター関数を使用して、このコードを興味深い方法でリファクタリングし、生成された要素を反復して連続する要素を出力できるようにすることができます。そのようです:
def my_printer(dictlist):
for d int dictlist: # renamed to not shadow dict
for key in dict:
print .format('{} ---> {}').format(key,dict[key])
yield
次に、次のような要素を印刷できます。
>>> p = my_printer(dictlist)
>>> p.next()
'some stuff 1'
>>> p.next()
'some stuff 2'
等。
それは本当にあなたが求めたものではありません。
質問にもっと直接的に答えるために、ステートメントを除外すると、ネストされたループprint
がフラット化されたように見えるものを取得できます。for
>>> (('{} ---> {}').format(k,v) for d in dictlist for k,v in d.items())
または、実際(k,v)
には同じ順序で渡すタプルにすぎないため、splat 演算子を使用して、パラメーターとして呼び出し*
に直接展開できます。format
>>> (('{} ---> {}').format(*p) for d in dictlist for p in d.items())
最後に、代わりに次の関数d.items()
を使用して、 の中間リスト作成を削除したい場合があります。iteritems
>>> (('{} ---> {}').format(*p) for d in dictlist for p in d.iteritems())
ただし、通常の for ループで結果を出力します。
>>> for x in _:
print x
key2 ---> value2
key1 ---> value1
key3 ---> value3
key4 ---> value4