Pythonic方法结合FOR循环和IF语句

Che*_*nks 244 python loops for-loop if-statement

我知道如何在单独的行上使用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
Run Code Online (Sandbox Code Playgroud)

而且我知道当语句很简单时我可以使用列表理解来组合这些,例如:

print([x for x in xyz if x in a])
Run Code Online (Sandbox Code Playgroud)

但是我找不到的是一个很好的例子(复制和学习)演示了一组复杂的命令(不仅仅是"print x"),这些命令是在for循环和一些if语句的组合之后发生的.我期望的东西看起来像:

for x in xyz if x not in a:
    print(x...)
Run Code Online (Sandbox Code Playgroud)

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

Kug*_*gel 292

您可以使用这样的生成器表达式:

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

for x in gen:
    print x
Run Code Online (Sandbox Code Playgroud)

  • 我真的很想念python能够在xyz中说x为x,如果x:` (111认同)
  • 可能,但不比原来的和if块好. (7认同)
  • `for x in(x代表xyz中的x,如果x不在a中):`对我有效,但是为什么你不应该只能在xyz中为x做x如果x不在a:中,我不是当然... (7认同)

Joh*_*web 31

根据Python的Zen(如果你想知道你的代码是否是"Pythonic",那就是去的地方):

  • 美丽胜过丑陋.
  • 显式优于隐式.
  • 简单比复杂更好.
  • Flat优于嵌套.
  • 可读性很重要.

获得两个s 的Pythonic方法是:sorted intersectionset

>>> sorted(set(a).intersection(xyz))
[0, 4, 6, 7, 9]
Run Code Online (Sandbox Code Playgroud)

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

>>> sorted(set(xyz).difference(a))
[12, 242]
Run Code Online (Sandbox Code Playgroud)

但是对于一个更复杂的循环,你可能想要通过迭代一个名字很好的生成器表达式和/或调用一个名字很好的函数来展平它.试图将所有东西都放在一条线上很少是"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
Run Code Online (Sandbox Code Playgroud)

  • @Johnsyweb,如果你要引用Python的禅:"应该有一个 - 最好只有一个 - 明显的做法." (2认同)

Ale*_*lex 15

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

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
Run Code Online (Sandbox Code Playgroud)

编辑

如果您非常希望避免使用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)))
Run Code Online (Sandbox Code Playgroud)

  • `filter(a .__ contains _,xyz)`.通常当人们使用lambda时,他们确实需要更简单的东西. (4认同)

jav*_*dba 13

以下是接受答案的简化/单线程:

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
Run Code Online (Sandbox Code Playgroud)

请注意,它generator内联的.这是测试python2.7python3.6 (注意print;中的parens ))


Kra*_*mar 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])
Run Code Online (Sandbox Code Playgroud)


Wim*_*jen 9

我可能会用:

for x in xyz: 
    if x not in a:
        print x...
Run Code Online (Sandbox Code Playgroud)


Kha*_*Rok 7

我喜欢亚历克斯的回答,因为过滤器正是应用于列表的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)
Run Code Online (Sandbox Code Playgroud)

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

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

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

for x in filter(wanted, mylist):
    print(x)
Run Code Online (Sandbox Code Playgroud)

当您不需要列表的成员,而是对所述成员进行修改时,生成器方法似乎更好,这似乎更适合生成

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)
Run Code Online (Sandbox Code Playgroud)

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

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)
Run Code Online (Sandbox Code Playgroud)

但当然,像这样写仍然很好:

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)
Run Code Online (Sandbox Code Playgroud)


Lau*_*low 5

如果生成器表达式过于复杂或复杂,您也可以使用生成器:

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

for x in gen():
    print x
Run Code Online (Sandbox Code Playgroud)