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

我知道如何使用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]) 

但是我无法find的是一个很好的例子(复制和学习),演示了一个复杂的命令集合(不仅仅是“print x”),这个命令在for循环和一些if语句的结合之后发生。 我期望的东西是这样的:

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

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

你可以使用这样的生成器expression式 :

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

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

  • 美丽胜过丑陋。
  • 显式比隐式更好。
  • 简单胜于复杂。
  • 平面比嵌套更好。
  • 可读性计数。

Pythonic获得两个setintersection的方式是:

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

或者这些元素是xyz但不在:

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

但是对于一个更复杂的循环,你可能想要通过迭代一个命名好的生成器expression式和/或调用一个命名好的函数来压平它。 试图把所有东西放在一条线上很less是“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 

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

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

我可能会使用:

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

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

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

使用intersectionintersection_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就是你的答案