Pythonic способ объединить цикл FOR и оператор IF - PullRequest
230 голосов
/ 08 августа 2011

Я знаю, как использовать как для циклов, так и для операторов 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])

Но я нигде не могу найти хороший пример (для копирования и изучения), демонстрирующий сложный набор команд (а не просто «print x»), которые происходят после комбинации комбинациицикл и некоторые операторы if.Что-то, что я ожидаю, выглядит следующим образом:

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

Разве это не так, как предполагается, что питон работает?

Ответы [ 8 ]

279 голосов
/ 08 августа 2011

Вы можете использовать генератор выражений , например:

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

for x in gen:
    print x
31 голосов
/ 08 августа 2011

Согласно Zen of Python (если вам интересно, является ли ваш код "Pythonic", это то место, куда можно пойти):

  • Красиво лучше, чем безобразно.
  • Явное лучше, чем неявное.
  • Простое лучше, чем сложное.
  • Плоское лучше, чем вложенное.
  • Читаемость имеет значение.

Пифонический способ получения sorted intersection из двух set s:

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

Или те элементы, которые xyz, но не в a:

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

Но для более сложного цикла вы можете захотеть сгладить его, выполнив итерацию по хорошо названному выражению генератора и / или вызов хорошо названной функции.Попытка поместить все в одну строку редко бывает "пифонической".


Обновите после дополнительных комментариев на ваш вопрос и принятого ответа

Я не уверен, что вы пытаетесь сделатьс enumerate, но если a является словарем, вы, вероятно, захотите использовать ключи, например так:

>>> 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
13 голосов
/ 23 декабря 2011

Я лично считаю, что это самая красивая версия:

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)))
10 голосов
/ 05 марта 2018

Ниже приведено упрощение / один вкладыш из принятого ответа:

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.7 и python3.6 (обратите внимание на символы в print;))

9 голосов
/ 19 февраля 2014

Я бы, наверное, использовал:

for x in xyz: 
    if x not in a:
        print x...
9 голосов
/ 08 августа 2011
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])
5 голосов
/ 08 августа 2011

Вы также можете использовать генераторы , если выражения генератора становятся слишком сложными или сложными:

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

for x in gen():
    print x
2 голосов
/ 27 мая 2015

Использование 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 ваш ответ

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...