python - 短路列表理解

标签 python list-comprehension generator-expression

<分区>

有好几次,我都希望使用 python 语法来缩短列表推导式或生成器表达式。

这是一个简单的列表理解,以及 python 中的等效 for 循环:

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 中的等效 for 循环:

[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) 作为一个选项,但是:

  • 它不是特别 pythonic - 不像 while comprehension 那样可读
  • 它可能无法像 CPython 理解一样高效或快速
  • 它需要一个额外的步骤来转换输出,而这可以直接放入理解中,例如[x.lower() for x in mylist]
  • 甚至original author doesn't seem to like it much .

我的问题是,关于为什么将语法扩展到这个用例不是一个好主意,或者只是不可能因为 python 开发人员认为它很少有用,是否存在任何理论上的问题?这似乎是对该语言的一个简单补充,也是一个有用的功能,但我可能忽略了一些隐藏的微妙之处或复杂性。

相关:thisthis

最佳答案

事实证明,正如@Paul McGuire 指出的那样,它已在 PEP 3142 中提出。得到了rejected通过圭多:

I didn't know there was a PEP for that. I hereby reject it. No point wasting more time on it.

不过,他没有给出任何解释。在邮件列表中,反对它的一些观点是:

  • [理解是] 精心设计的多个嵌套语句和单个表达式之间的一对一转换。但是这个提议忽略并破坏了它。(here)。”也就是说,while 关键字不对应于显式循环中的 while - 它只是一个 break
  • “它让 Python 更难学,因为它增加了一个要学的东西。” (引用here)
  • 它增加了生成器表达式和列表理解之间的另一个区别。似乎将此语法添加到列表理解中也是绝对不可能的。

我认为与通常的列表理解的一个基本区别是 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 只是一个可迭代对象,则不可能短路。

关于python - 短路列表理解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16931214/

相关文章:

python - 如何识别生成器与列表理解

python - 将元素追加到 Python 字典的多个键

python - 具有多个 for 子句的列表理解的 Map/reduce 等价物

c# - C# 有什么可以与 Python 的列表推导相媲美的吗?

python - 列表推导式创建成对差异

python - 在初始化时填充一个 defaultdict

python - Python 3 中 `list(generator expression)` 的列表理解语法糖吗?

python - 使用 numpy 广播/矢量化从其他数组构建新数组

python - Python 中的协程 : Best Practices

python - 如何在 Windows XP 源安装上消除 matplotlib 中的 ft2font 导入错误?