有几次我想要python语法来缩短列表推导或生成器表达式。
这是一个简单的列表推导,以及python中循环的等价物:
my_list = [1, 2, 3, 'potato', 4, 5]
[x for x in my_list if x != 'potato']
result = []
for element in my_list:
if element != 'potato':
result.append(element)
在语言中不支持理解短路。提出的语法,以及python中循环的等价物:
[x for x in my_list while x != 'potato']
# --> [1, 2, 3]
result = []
for element in my_list:
if element != 'potato':
result.append(element)
else:
break
它应该适用于任意迭代,包括无限序列,并且可以扩展到生成器表达式语法。我知道list(itertools.takewhile(lambda x: x != 'potato'), my_list)
是一个选项,但是:
[x.lower() for x in mylist]
我的问题是,是否有任何理论上的皱纹为什么将语法扩展到这个用例并不是一个好主意,或者它是不可能的因为python dev认为它很少有用?它似乎是对语言的简单补充,也是一个有用的功能,但我可能会忽略一些隐藏的细微之处或并发症。
答案 0 :(得分:6)
正如@Paul McGuire指出的那样,它是由Guido在PEP 3142和rejected中提出的:
但是,他没有给出解释。在邮件列表中,反对它的一些要点是:我不知道有一个PEP。我在此拒绝。没有意义 浪费更多时间。
while
关键字与显式循环中的while
不对应 - 它只是break
。我认为与通常的列表理解的一个基本区别是while
本质上是命令性的,而不是声明性的。它取决于并指示执行的顺序,而语言(AFAIK)无法保证。我想这就是它不包含在Haskell的理解中的原因,python从中理解了这个想法。
当然,生成器表达式确实有方向,但它们的元素可能是预先计算的 - 再次,AFAIK。提到的PEP确实建议仅用于生成器表达式 - 这是有道理的。
当然,Python 无论如何都是一种命令式语言,但它会引发问题。
选择一个无序的集合怎么样?
[x for x in {1,2,3} while x!=2]
你也没有在简单的for
循环中使用它,但这是你无法用语言强制执行的东西。 takewhile
回答了这个问题,但这是一个随意的答案。
最后一点,请注意,为了保持一致性,您需要支持dropwhile
。
[x for x in my_list from x != 'potato']
与等效for
构造的关系更少,如果my_list
只是可迭代的话,这次不可能短路。