我知道如何在单独的行上使用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的工作方式吗?
答案 0 :(得分:275)
您可以像这样使用generator expressions:
gen = (x for x in xyz if x not in a)
for x in gen:
print x
答案 1 :(得分:30)
根据The Zen of Python(如果你想知道你的代码是否是“Pythonic”,那就是去的地方):
获取两个sorted
的intersection
set
的Pythonic方法是:
>>> sorted(set(a).intersection(xyz))
[0, 4, 6, 7, 9]
或xyz
但不在a
中的那些元素:
>>> sorted(set(xyz).difference(a))
[12, 242]
但是对于一个更复杂的循环,你可能想通过迭代一个名字很好的generator expression和/或调用一个名字很好的函数来展平它。试图将所有东西都放在一条线上很少是“Pythonic”。
我不确定你要对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
答案 2 :(得分:13)
我个人认为这是最漂亮的版本:
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,可以使用部分函数应用程序并使用运算符模块(提供大多数运算符的函数)。
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)))
答案 3 :(得分:9)
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])
答案 4 :(得分:9)
我可能会使用:
for x in xyz:
if x not in a:
print x...
答案 5 :(得分:9)
以下是接受答案中的简化/单线:
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
中的parens;)
答案 6 :(得分:5)
如果生成器表达式过于复杂或复杂,您也可以使用generators:
def gen():
for x in xyz:
if x in a:
yield x
for x in gen():
print x
答案 7 :(得分:2)
使用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
就是您的回答
答案 8 :(得分:1)
找到列表a和b的唯一公共元素的简单方法:
a = [1,2,3]
b = [3,6,2]
for both in set(a) & set(b):
print(both)
答案 9 :(得分:0)
我喜欢Alex's answer,因为过滤器恰好是应用于列表的 if ,因此,如果要浏览给定的列表的子集,条件,这似乎是最自然的方法
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)