当前位置: 首页 > 面试题库 >

for循环名称列表表达式合法吗?

姜钧
2023-03-14
问题内容

在CPython 2.7.10和3.4.3以及PyPy 2.6.0(Python
2.7.9)中,在for循环中将表达式(或其中的一些子集)用于名称列表显然是合法的。这是一个典型的for循环:

>>> for a in [1]: pass
...
>>> a
1

但是您也可以使用对象的属性:

>>> class Obj(object): pass
...
>>> obj = Obj()
>>> for obj.b in [1]: pass
...
>>> obj.b
1

您甚至可以使用表达式中的属性:

>>> for Obj().c in [1]: pass
...

但是,并非所有的表达式都起作用:

>>> for (True and obj.d) in [1]: pass
...
  File "<stdin>", line 1
SyntaxError: can't assign to operator

但是,只要属性在外面,它们就起作用了吗?

>>> for (True and obj).e in [1]: pass
...
>>> obj.e
1

还是可以分配的?

>>> for {}['f'] in [1]: pass
...

我很惊讶这些都是Python中的合法语法。我希望只允许使用名字。这些甚至应该起作用吗?这是疏忽吗?这是PyPy也恰好实现的CPython的实现细节吗?


问题答案:

这些甚至应该起作用吗?

这是疏忽吗?

没有

这是PyPy也恰好实现的CPython的实现细节吗?

没有

如果可以分配给它,则可以将其用作for循环中的自由变量。

对于这样的问题,值得直接学习语法:

for_stmt ::=  "for" target_list "in" expression_list ":" suite
              ["else" ":" suite]

Atarget_list只是一堆target

target_list     ::=  target ("," target)* [","]
target          ::=  identifier
                     | "(" target_list ")"
                     | "[" [target_list] "]"
                     | attributeref
                     | subscription
                     | slicing
                     | "*" target

如果仔细观察,您会发现您给出的所有工作示例都不是反例。请注意,解析器中的错误并不是闻所未闻的,因此,如果您发现合法的语法异常,则可以提交票证-这些错误会很快得到解决。

您给出的最有趣的一对是(True and obj.d)(True and obj).d,它们在逻辑上似乎相同,但解析方式不同:

>>> ast.dump(ast.parse('(True and obj.d)'), annotate_fields=False)
"Module([Expr(BoolOp(And(), [Name('True', Load()), Attribute(Name('obj', Load()), 'd', Load())]))])"
>>> ast.dump(ast.parse('(True and obj).d'), annotate_fields=False)
"Module([Expr(Attribute(BoolOp(And(), [Name('True', Load()), Name('obj', Load())]), 'd', Load()))])"

注意: (True and obj).dattributeref语法中的一个。



 类似资料:
  • 问题内容: 我有以下代码: 我想知道Python使用该方法对列表进行了多少次排序?是每次迭代还是一次? 换句话说,以下代码更有效吗? 问题答案: 在两个代码示例中,列表仅排序一次。 在开始循环之前,仅对一次for循环标头中运算符右侧的表达式求值。您可以在文档中阅读: 表达式列表被评估一次 ; 它应该产生一个可迭代的对象。 实际上,第二个代码示例效率 较低, 因为存在不必要的分配。

  • 问题内容: 据我了解,lambda表达式捕获值,而不是变量。例如,以下是编译时错误: 但是,当我尝试使用增强功能运行相同的逻辑时,一切工作正常: 为什么它对于增强型循环而不是常规的常规循环都能很好地工作,尽管增强型循环也像常规循环那样在内部递增变量。** 问题答案: Lambda表达式的工作方式类似于回调。一旦在代码中传递它们,它们就“存储”它们需要操作的任何外部值(或引用)(就像这些值在函数调用

  • 问题内容: 刚刚开始探索正则表达式的“奇迹”。作为一个从试验和错误中学习的人,我真的很努力,因为我的试验抛出了不成比例的错误……我的实验是在PHP中使用ereg()进行的。 无论如何。我分别使用名字和姓氏,但现在使用相同的正则表达式。到目前为止,我有: 任何以大写字母开头且其余仅包含字母(大写或不大写)的长度字符串。但是我分崩离析的地方是在几乎任何地方都可能发生的特殊情况下。 连字符(Worthi

  • 问题内容: 以下是提供输出的代码段:。由于访问列表中的数字3,我期望获得输出。在线给出的解释是“每次迭代中更改的价值”,但我不太了解如何或为什么。任何解释都很好! 问题答案: 这里发生的是一个列表在循环过程中发生了变异。 让我们考虑以下代码片段: 输出为: 每次迭代: 从内部指针当前指向的位置读取值 立即将其分配给列表中的最后一个元素 在最后一个元素打印在标准输出上之后 就像这样: 内部指针指向第

  • 我有一个两个项目的列表,每个项目是一个文本字符串。我想围绕这两个项目循环,如果一个单词不在一组单词中,则基本上删除它。但是,下面的代码将所有单词放在一起,而不是创建两个单独的项。我希望我的更新列表包含两个项目,每个原始项目对应一个im更新:

  • 问题内容: 我很好奇:这两个循环实现之间在速度和性能上是否有所不同?假定 size() 方法返回处理一组元素的数组,集合或对象的长度(实际上是来自 XOM api)。 实施1: 实施2: 问题答案: 从性能的角度来看,没有什么区别。这是因为可以优化循环,以便内联size()查找,从而导致很小的性能差异。 主要区别在于循环时大小是否改变。第一种情况将尝试迭代固定次数。在第二种情况下,迭代次数将取决于

  • 问题内容: 如果输入为 我需要输出为 我试过了 但是它给出了错误 如何修改代码以获得所需的输出? 问题答案: 您可以在此处找到一系列迭代方法:http : //docs.python.org/2.7/library/itertools.html#recipes 编辑 :Python 3 https://docs.python.org/3/library/itertools.html#itertoo

  • 我有一个网络应用编程接口,多个列表,和一个从网络应用编程接口查询数据的函数。我已经设法手动更新列表,一次一个。然而,数据有多个列(列表将包含列的数据),并且有38个列表并手动调用函数来更新它们是很麻烦的。我设计了一个简短的for循环来迭代列表,并相应地更新它们。但是,更新后的列表不会返回;或者甚至没有更新。如何在代码中修复此问题?请参阅下面的代码,虽然我不能提供API上的数据: =========