【问题标题】:nested list comprehensions嵌套列表推导
【发布时间】:2012-08-09 16:36:35
【问题描述】:

我尝试在内部列表中使用外部列表理解的值:

[ x for x in range(y) for y in range(3) ]

但不幸的是,这会引发 NameError,因为名称 y 是未知的(尽管外部列表理解指定了它)。

这是 Python 的限制(2.7.3 和 3.2.3 已尝试)还是有充分的理由无法正常工作?

是否有计划摆脱限制?

是否有解决方法(一些不同的语法可能我没有弄清楚)来实现我想要的?

【问题讨论】:

  • 记住顺序的一个好方法是考虑在没有列表理解的情况下如何执行此操作(最近有人提到了这一点,但它卡住了)

标签: python list syntax list-comprehension


【解决方案1】:

您说的是列表理解,而不是生成器表达式。

你需要交换你的 for 循环:

[ x for y in range(3) for x in range(y) ]

您需要像嵌套在常规循环中一样阅读这些内容:

for y in range(3):
    for x in range(y):
        x

具有多个循环的列表推导遵循相同的顺序。见list comprehension documentation

提供列表解析时,它由一个表达式组成,后跟至少一个 for 子句和零个或多个 forif 子句。在这种情况下,新列表的元素是通过将每个 forif 子句视为一个块、从左到右嵌套并在每次到达最里面的块。

当然,生成器表达式也是如此,但它们使用 () 括号而不是方括号,并且不会立即实现:

>>> (x for y in range(3) for x in range(y))
<generator object <genexpr> at 0x100b50410>
>>> [x for y in range(3) for x in range(y)]
[0, 0, 1]

【讨论】:

  • 谢谢!我觉得这让我大开眼界 :-) 不过,我觉得有点令人惊讶的是,这个订单是预期的。
  • 我一直认为列表推导是使用生成器来描述列表。这种观点是错误的还是有任何危险?
  • 我将术语“生成器”更改为“理解”。
  • @Alfe:一点点。您无法从无穷无尽的生成器(如itertools.count())创建列表,但您可以有效地从此类生成器表达式中绘制项目,只要您不希望它在某个时候完成。
  • +1 感谢 Martijn,直到现在我才明白这个顺序。 (可能与“除非你是荷兰人否则不明显”的事情有关。)
【解决方案2】:

你试过了吗:

[x for y in range(3) for x in range(y)]

因为这会产生一个输出......这会产生:

[0, 0, 1]

这可能是你想要的,也可能不是你想要的......

【讨论】:

  • 这就是我想要的,是的。当然,我的用例要复杂一些:
  • return [targetSet 中目标的值作为主题,self.db[target].keys() 中的值 if topic == selectedTopic ]
  • @Levon,有时答案会同时发布。一旦我点击提交,我发现其他人打败了我。然后我决定添加运行它的输出,因为其他人没有包括它(还 - 我还没有检查)。
  • 实际上它变成了这样:list(set(value for target in targetSet for topic, values in self.db[target].iteritems() if topic == chosenTopic for value in values if (topic, value) not in trail))。我想知道是否有人能猜到我现在在做什么;-)
  • 还有一件事:set([ topic for target in targetSet for topic, values in self.db[target].iteritems() if set((topic, value) for value in values) - trail ])。但现在我跑题了,抱歉。
【解决方案3】:

只需嵌套另一代。

[ x for x in [range(y) for y in range(3) ]]

给我:

[[], [0], [0, 1]]

【讨论】:

  • 但是列表列表不是我需要的。还是谢谢。
  • @Alfe 你的问题不是很清楚。然后用martijns回答。 :)
猜你喜欢
  • 1970-01-01
  • 2023-03-06
  • 2017-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-26
  • 2021-04-25
  • 1970-01-01
相关资源
最近更新 更多