如果您使用的是Python 3.8或更高版本,则可以使用
赋值运算符(也称为
海象运算符)在列表推导式内创建新的本地名称并对其进行赋值。对于您的特定示例,您需要在
<=
比较的左操作数中执行此操作。
sums = [
s
for k in keyboards
for d in drivers
if (s := k + d) <= upper_limit
]
请注意,在这里必须使用括号将赋值括起来,因为太阳眼镜运算符是
所有Python运算符中优先级最低的。如果没有括号,您将把
k + d <= upper_limit
的结果分配给
s
,因此是一个布尔值。
请注意,
s
将在周围的范围内可见,名称
s
的作用域与
sums
相同;在函数内部为局部,在模块级别运行列表推导式时为全局。另一方面,
k
和
d
是列表推导循环的本地变量,并且在推导之外不可见。
演示:
>>> keyboards = [3, 1]
>>> drivers = [5, 2, 8]
>>> upper_limit = 10
>>> [s for k in keyboards for d in drivers if (s := k + d) <= upper_limit]
[8, 5, 6, 3, 9]
>>> s
9
>>> k
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'k' is not defined
在早期的Python版本中,只有在
for
循环的目标名称中才能使用列表推导式来将其赋值给一个新名称,因此如果您需要一个“本地”变量来引用一个计算,您需要找到添加额外循环的方法。所以在Python 3.7或更早版本中,您可以添加另一个循环来计算
k + d
的单个元组。
sums = [
s
for k in keyboards
for d in drivers
for s in (k + d,)
if s <= upper_limit
]
(k + d,)
是一个单元素元组,因此for s in (k + d,)
对于每次迭代keyboards
和drivers
都只执行一次,有效地将k + d
分配给s
。
您还可以使用生成器表达式为两个嵌套的for
循环生成k + d
总和,然后迭代该表达式的结果:
sums = [
s
for s in (
k + d
for k in keyboards
for d in drivers
)
if s <= upper_limit
]
在后一种情况下,您可以先将该表达式存储为单独的变量:
s_calc = (k + d for k in keyboards for d in drivers)
sums = [s for s in s_calc if s <= upper_limit]
使用这些选项,
s
始终局限于推导循环中,并且在
sums
作用域级别不可见。它不会“泄漏”出推导表达式。
后面没有需要翻译的内容了。
>>> [s for k in keyboards for d in drivers for s in (k + d,) if s <= upper_limit]
[8, 5, 6, 3, 9]
>>> [s for s in (k + d for k in keyboards for d in drivers) if s <= upper_limit]
[8, 5, 6, 3, 9]
>>> s_calc = (k + d for k in keyboards for d in drivers)
>>> [s for s in s_calc if s <= upper_limit]
[8, 5, 6, 3, 9]