it-swarm.dev

Modo Pythonic per combinare l'istruzione FOR loop e IF

So come usare entrambi i cicli e se le istruzioni su righe separate, come ad esempio:

>>> 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

E so che posso usare una comprensione delle liste per combinarle quando le affermazioni sono semplici, come ad esempio:

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

Ma ciò che non riesco a trovare è un buon esempio da nessuna parte (copiare e imparare da) che dimostra un insieme complesso di comandi (non solo "print x") che si verificano in seguito a una combinazione di un ciclo for e alcune istruzioni if. Qualcosa che mi aspetterei assomiglia a:

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

Questo non è il modo in cui Python dovrebbe funzionare?

226
ChewyChunks

Puoi usare espressioni del generatore in questo modo:

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

for x in gen:
    print x
276
Kugel

Come per The Zen of Python (se ti stai chiedendo se il tuo codice è "Pythonic", questo è il posto dove andare):

  • Bello è meglio che brutto.
  • L'esplicito è meglio che implicito.
  • Semplice è meglio che complesso.
  • Flat è meglio di nidificato.
  • Conta la leggibilità.

Il modo Pythonic di ottenere il sortedNAME _intersectionNAME _ di due setNAME _ s è:

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

O quegli elementi che sono xyzma non in aname__:

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

Ma per un ciclo più complicato potresti voler appiattirlo iterando su un ben noto espressione del generatore e/o chiamando ad una funzione ben denominata . Cercare di montare tutto su una linea è raramente "Pythonic".


Aggiorna seguendo i commenti aggiuntivi sulla tua domanda e la risposta accettata

Non sono sicuro di cosa stai cercando di fare con enumerateNAME _ , ma se aè un dizionario, probabilmente vorrai usare le chiavi, in questo modo:

>>> 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

Personalmente penso che questa sia la versione più carina:

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

Modificare

se si desidera evitare l'uso di lambda, è possibile utilizzare l'applicazione di funzione parziale e utilizzare il modulo operatore (che fornisce le funzioni della maggior parte degli operatori).

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

Quello che segue è una semplificazione/una fodera della risposta accettata:

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

Si noti che generator è stato mantenuto inline . Questo è stato testato su python2.7 e python3.6 (notare i parenti nel print;))

9
javadba

Probabilmente userò:

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

Puoi usare anche i generatori , se le espressioni del generatore diventano troppo coinvolte o complesse:

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

for x in gen():
    print x
5

Utilizza intersection o intersection_update

  • intersezione :

    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)
    

    allora b è la tua risposta

2
Chung-Yen Hung