web-dev-qa-db-ja.com

FORループとIFステートメントを組み合わせるPythonicの方法

次のように、forループとifステートメントの両方を別々の行に使用する方法を知っています。

>>> a = [2,3,4,5,6,7,8,9,0]
... xyz = [0,12,4,6,242,7,9]
... for x in xyz:
...     if x in a:
...         print(x)
0,4,6,7,9

そして、文が単純な場合は、リスト内包表記を使用してこれらを組み合わせることができます。たとえば、

print([x for x in xyz if x in a])

しかし、私が見つけることができないのは、forループといくつかのifステートメントの組み合わせの後に発生する複雑なコマンドのセット(単に "print x"ではない)を示す(コピーして学ぶことができる)場所の良い例です。私が期待することは何かのようになります:

for x in xyz if x not in a:
    print(x...)

これはPythonが機能するはずの方法ではないのでしょうか。

226
ChewyChunks

次のように ジェネレータ式 を使用できます。

gen = (x for x in xyz if x not in a)

for x in gen:
    print x
276
Kugel

Pythonの禅 に従って(あなたのコードが "Pythonic"であるかどうか疑問に思っているなら、それは行くべき場所です):

  • 美しさは醜いよりも優れています。
  • 明示的は暗黙的より優れています。
  • 単純は複雑よりも優れています。
  • フラットは入れ子よりも優れています。
  • 読みやすさが重要です。

sortedNAME _intersectionNAME _ のうち2つ setNAME _ を取得するPythonicの方法は、次のとおりです。

>>> sorted(set(a).intersection(xyz))
[0, 4, 6, 7, 9]

あるいはxyzname__であるがaname__にはない要素:

>>> sorted(set(xyz).difference(a))
[12, 242]

しかし、もっと複雑なループの場合は、よく使われている ジェネレータ式 を繰り返したり、よく使われている関数を呼び出したりしてフラット化することをお勧めします。すべてを1行に収めることを試みることがめったに「Pythonic」になることはありません。


あなたの質問と受け入れられた答えについての追加コメントに従って更新してください

enumerateNAME _ で何をしようとしているのかわかりませんが、aname__が辞書の場合は、おそらく次のようにキーを使用します。

>>> a = {
...     2: 'Turtle Doves',
...     3: 'French Hens',
...     4: 'Colly Birds',
...     5: 'Gold Rings',
...     6: 'Geese-a-Laying',
...     7: 'Swans-a-Swimming',
...     8: 'Maids-a-Milking',
...     9: 'Ladies Dancing',
...     0: 'Camel Books',
... }
>>>
>>> xyz = [0, 12, 4, 6, 242, 7, 9]
>>>
>>> known_things = sorted(set(a.iterkeys()).intersection(xyz))
>>> unknown_things = sorted(set(xyz).difference(a.iterkeys()))
>>>
>>> for thing in known_things:
...     print 'I know about', a[thing]
...
I know about Camel Books
I know about Colly Birds
I know about Geese-a-Laying
I know about Swans-a-Swimming
I know about Ladies Dancing
>>> print '...but...'
...but...
>>>
>>> for thing in unknown_things:
...     print "I don't know what happened on the {0}th day of Christmas".format(thing)
...
I don't know what happened on the 12th day of Christmas
I don't know what happened on the 242th day of Christmas
31
Johnsyweb

私は個人的にこれが最も美しいバージョンだと思います:

a = [2,3,4,5,6,7,8,9,0]
xyz = [0,12,4,6,242,7,9]
for x in filter(lambda w: w in a, xyz):
  print x

編集する

ラムダを使わないようにしたい場合は、部分関数アプリケーションを使用して(ほとんどの演算子の機能を提供する)演算子モジュールを使用することができます。

https://docs.python.org/2/library/operator.html#module- operator

from operator import contains
from functools import partial
print(list(filter(partial(contains, a), xyz)))
13
Alex

以下は、受け入れられた答えからの単純化/ 1つの裏書きです。

a = [2,3,4,5,6,7,8,9,0]
xyz = [0,12,4,6,242,7,9]

for x in (x for x in xyz if x not in a):
    print(x)

12
242

generatorはインラインで保持されていたことに注意してください。これはpython2.7python3.6でテストされました(print;の中のペアに注意してください)。

9
javadba

私はおそらく使用します:

for x in xyz: 
    if x not in a:
        print x...
9
Wim Feijen
a = [2,3,4,5,6,7,8,9,0]
xyz = [0,12,4,6,242,7,9]  
set(a) & set(xyz)  
set([0, 9, 4, 6, 7])
9
Kracekumar

ジェネレータの式が複雑すぎたり複雑になったりする場合は、 ジェネレータ も使用できます。

def gen():
    for x in xyz:
        if x in a:
            yield x

for x in gen():
    print x
5

intersectionまたはintersection_updateを使用

  • 交差点

    a = [2,3,4,5,6,7,8,9,0]
    xyz = [0,12,4,6,242,7,9]
    ans = sorted(set(a).intersection(set(xyz)))
    
  • intersection_update

    a = [2,3,4,5,6,7,8,9,0]
    xyz = [0,12,4,6,242,7,9]
    b = set(a)
    b.intersection_update(xyz)
    

    それならbがあなたの答えです

2
Chung-Yen Hung