结合for-loop和if-statement的python方式

我知道如何在单独的行上使用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])

但是我在任何地方都找不到一个很好的例子(可以复制和学习)来演示一组复杂的命令(不仅仅是“print x”),这些命令发生在for循环和一些if语句的组合之后。我期待的是这样的:

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

这不是python应该工作的方式吗?

619923 次浏览

你可以像这样使用生成器表达式:

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


for x in gen:
print(x)
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])

根据Python的禅宗(如果你想知道你的代码是否是“Pythonic”,那就是你要去的地方):

  • 美总比丑好。
  • 显性比隐性好。
  • 简单比复杂好。
  • 扁平比嵌套好。
  • 可读性。

python获取两个__abc5的sorted intersection的方法是:

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

或者那些属于xyz但不在a中的元素:

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

但是对于一个更复杂的循环,你可能想要通过迭代一个命名良好的生成器表达式和/或调用一个命名良好的函数来将它变平。试图将所有内容都放在一行上很少是“python式的”。


更新以下关于您的问题和接受的答案的其他评论

我不确定你想用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

如果生成器表达式太复杂,你也可以使用发电机:

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


for x in gen():
print x

我个人认为这是最漂亮的版本:

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

编辑

如果你非常热衷于避免使用lambda,你可以使用部分函数应用程序和使用operator模块(它提供了大多数操作符的函数)。

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

我可能会用:

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

使用intersectionintersection_update

  • < p > 十字路口:

    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是你的答案

以下是对公认答案的简化/一行:

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中的paren;))

尽管如此,它确实很麻烦:x被提到了四个次。

我喜欢亚历克斯的回答,因为过滤器恰好是应用于列表的如果,所以如果你想在给定条件下探索列表的子集,这似乎是最自然的方法

mylist = [1,2,3,4,5]
another_list = [2,3,4]


wanted = lambda x:x in another_list


for x in filter(wanted, mylist):
print(x)

这个方法对于分离关注点很有用,如果条件函数改变了,唯一需要修改的代码就是函数本身

mylist = [1,2,3,4,5]


wanted = lambda x:(x**0.5) > 10**0.3


for x in filter(wanted, mylist):
print(x)

当你不想要列表中的成员时,发电机方法似乎更好,而是对这些成员进行修改,这似乎更适合发电机

mylist = [1,2,3,4,5]


wanted = lambda x:(x**0.5) > 10**0.3


generator = (x**0.5 for x in mylist if wanted(x))


for x in generator:
print(x)

此外,过滤器与生成器一起工作,尽管在这种情况下效率不高

mylist = [1,2,3,4,5]


wanted = lambda x:(x**0.5) > 10**0.3


generator = (x**0.9 for x in mylist)


for x in filter(wanted, generator):
print(x)

当然,这样写还是不错的:

mylist = [1,2,3,4,5]


wanted = lambda x:(x**0.5) > 10**0.3


# for x in filter(wanted, mylist):
for x in mylist if wanted(x):
print(x)

找到列表A和b的唯一公共元素的简单方法:

a = [1,2,3]
b = [3,6,2]
for both in set(a) & set(b):
print(both)

根据这里的文章:https://towardsdatascience.com/a-comprehensive-hands-on-guide-to-transfer-learning-with-real-world-applications-in-deep-learning-212bf3b2f27a 出于同样的原因,我使用了以下代码,它工作得很好:

an_array = [x for x in xyz if x not in a]

这一行是节目的一部分!这意味着XYZ是一个之前定义和赋值的数组,也是变量a

使用生成器表达式(选择的答案中推荐哪一个)会有一些困难,因为结果不是一个数组