【问题标题】:Can I use final value in if part of list comprehension?我可以在列表理解的一部分中使用最终值吗?
【发布时间】:2020-11-18 17:50:39
【问题描述】:

假设我有一个从 1 到 10 的数字列表。我想知道这些小于 1000 的数字的平方,而不关心实际数字。这是我正在尝试实现的一个简化示例,我想知道单个列表理解是否可以做到这一点。

我可以这样做:

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
squares_under_1000 = [n ** 2 for n in numbers if n ** 2 < 1000]
print(squares_under_1000) # Output: [1, 4, 27, 256]

问题是我需要使用两次实际的平方计算 - 我需要重复自己,如果操作很慢,那就是......慢。

我知道我也可以使用filter:

squares_under_1000 = list(filter(lambda sq: sq < 1000, [n ** 2 for n in numbers]))

但我的意思是不要以另一种方式这样做,因为我已经知道该怎么做。相反:是否可以使用列表推导来计算一个值并在我的推导的if 部分中使用该计算值?

【问题讨论】:

标签: python list-comprehension


【解决方案1】:

这是在 Python 3.8 中添加赋值表达式的基本原理之一:

>>> [ n2 for n in numbers if (n2 := n ** n) < 1000 ]
[1, 4, 27, 256]

【讨论】:

  • 我认为最好只链接到previous answers 而不是复制其中的信息。
  • 很高兴知道海象可以在这种情况下使用它,谢谢!
  • @chepner 是否可以将计算移至for 之前的部分?我遇到了语法错误,但感觉比在if 部分中使用它更自然:(
  • 否;过滤条件在值表达式之前被评估。 [ (p := n**n) for n in numbers if p &lt; 1000] 之类的失败是因为在第一次评估 p &lt; 1000 时尚未定义 p。
  • (不,你不能用p = 1; [(p := n**n) for n in numbers if p &lt; 1000]作弊,因为在计算新的n**n之前,你会比较previous n**n;你会得到[1, 4, 27, 256, 3125] 作为答案 4**4 &lt; 1000 在考虑 n == 5 时。)
【解决方案2】:

您的帖子要求输入小于 1000 的数字的平方,但您正在提高自己的数字;也就是说,x**x == x^x。我假设你想要 x^2 == x**2。

@chepner 对 Python 3.8 及更高版本有一个很好的答案。对于低于 python 3.8(或者如果你不喜欢海象运算符),嵌套列表理解可能是这里的票:

numbers = list(range(1,11))
sq_und_1000 = [v for v in [n**2 for n in numbers] if v < 1000]

【讨论】:

  • 有趣!谢谢。
【解决方案3】:

查一下。 (在字典里。)

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
squares = {n: n**2 for n in numbers}
[v for v in squares.values() if v < 1000]

编辑:也可以在第二行创建另一个列表理解,它会满足您的要求。但是如果您还需要原始数字,那么字典会更好。

附:你在原来的帖子中提到了 n。

【讨论】:

  • 使用字典的想法很有趣,但是看起来有点矫枉过正。我更喜欢filter 和lambda,因为我可以在一个表达式中关闭它。
  • 个人偏好:它比带有 lambda 启动的嵌套函数更好读。 :)
  • 我同意 lambda 在某些其他语言中的可读性不如匿名函数。我想知道性能如何。
  • 这会导致 O(n) 空间损失,这不一定是坏,但需要注意。
  • 同意。 OP 似乎更关心时间。
猜你喜欢
  • 1970-01-01
  • 2023-01-27
  • 1970-01-01
  • 2021-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-12
  • 2010-10-08
相关资源
最近更新 更多