当前位置: 首页 > 知识库问答 >
问题:

列表理解中vars()的Python 2和3的不同行为

唐修明
2023-03-14

我目前正在转换一个脚本从Python 2到Python 3。在调试时,我偶然发现了两个版本之间行为不同的部分代码。然而,我无法解释这种差异。

这是一台复制机:

variable_1 = "x"
variable_2 = "y"
list_of_variables = ['variable_1', 'variable_2']
existing_variables = vars()

print([variable for variable in list_of_variables if variable in vars()])
print([variable for variable in list_of_variables if variable in existing_variables])

Python 2.7.18显示以下输出:

['variable_1', 'variable_2']
['variable_1', 'variable_2']

而Python 3.9.0则显示:

[]
['variable_1', 'variable_2']

为什么第一个列表理解在Python 3中不起作用?为什么它在变量中存储vars()的内容时工作?

共有2个答案

谷星文
2023-03-14

在Python3中,vars()的行为类似于locals(),这意味着您的locals()在列表中是不同的。https://docs.python.org/3/library/functions.html#vars

轩辕炎彬
2023-03-14

两者都起作用:只是作用不同而已。

在Python3中,列表理解创建自己的局部作用域,以避免变量名泄漏到调用作用域中。在列表理解中调用vars()只是返回列表理解自身范围中定义的变量,而不是使用列表理解的范围。

从https://docs.python.org/3/reference/expressions.html#displays-for-lists-sets-and-dictionaries:

然而,除了最左边的for子句中的可迭代表达式之外,理解是在一个单独的隐式嵌套作用域中执行的。这可以确保分配给目标列表中的名称不会“泄漏”到封闭范围中。

 类似资料:
  • 问题内容: 以下测试失败: 换一种说法: 问题答案: 它们是不同的,因为生成器表达式和list comp中的值都是惰性计算的,即在中调用匿名函数时。 到那时,如果绑定到最后一个值-1。 因此,基本上,这就是列表理解的功能(对于genexp也是如此): 现在,lambda携带了一个引用的闭包,但在两种情况下均绑定为-1,因为这是为其分配的最后一个值。 如果要确保lambda接收到的当前值,请执行 这

  • 推荐:Python 2.7.x 与 Python 3.x 的主要差异

  • 我想知道是否有一种简洁的方法可以在存在相同行的情况下“折叠”熊猫数据帧。例如: df= 我需要的是: 它肯定应该包括 但如何有效地实现括号中的位,我感到困惑。

  • 问题内容: 加入列表: join 必须采取迭代。 显然,join的论点是,这是一个列表理解。 看这个: 现在,join的参数为,但结果相同。 为什么?是否str还会产生列表或可迭代项? 问题答案: 这称为生成器表达式,并在PEP 289中进行了说明。 生成器表达式和列表理解之间的主要区别在于前者不在内存中创建列表。 请注意,还有第三种编写表达式的方法:

  • 我使用嵌套的Select语句从表1中获得单行结果,我需要在同一行的末尾追加表3中的另一列(COLX)。我试过联合,但结果是两行。有什么建议吗? table2.colz和table3.colx是用来匹配条目的ID。这两个最终结果都符合要求。 编辑(进一步解释我的表结构) COLX是表3的ID,以匹配表2中的COLZ 表2 ID中的COL1与表1中的COL1匹配 结果我需要的是表1.col1,表1.c

  • 问题内容: 使用列表理解和生成器理解时,我得到不同的输出。这是预期的行为还是错误? 请考虑以下设置: 如果再运行以下代码,则会得到: 这是在python 3.6.0上: 问题答案: 在列表理解中,对表达式进行热切评估。在生成器表达式中,仅根据需要查找它们。 因此,当生成器表达式遍历时,它引用但仅在循环完成后查找,因此它仅对两个元组使用最新值。相比之下,列表推导会立即进行评估,因此它将创建第一个值为