理解列表理解

时间:2014-04-25 00:16:38

标签: python list-comprehension

我最近被介绍过列出理解,然而,我不确定我是否完全理解它们。

所以,我快速搜索了文档和谷歌。 我在数据结构上找到了docs部分。

https://docs.python.org/2/tutorial/datastructures.html

虽然这给了我一个关于它们如何工作的想法,但我称之为奇怪,我希望对它们的运作方式有一个更为成熟的理解。

以下是文档中的示例:

>>>[(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

如果我错了,请纠正我,但这就是我理解列表如何评估的方式。

  • 看起来列表理解从左到右进行评估。
  • 这种理解介绍了X和Y。
  • 然后按列表定义X和Y,并根据列表中的位置以及if条件进行评估。
  • 由于X被指定为第一个变量,就像嵌套for循环的外部一样,首先调用它并对Y的列表进行迭代。
  • if条件使得理解只产生与X迭代通过Y列表不相似的对。

如果我的理解不正确,请纠正我。 我欢迎更复杂的理解例子。

1 个答案:

答案 0 :(得分:7)

嵌套列表推导没有什么神奇之处。我认为你还没有看到他们的简洁!

此:

#      X           A                   B               C
a = [(x, y)   for x in [1,2,3]   for y in [3,1,4]   if x != y]

只是语法糖:

__tmp = []
for x in [1,2,3]:                   # A
    for y in [3,1,4]:               # B
        if x != y:                  # C
            __tmp.append((x, y))    # X

a = __tmp

所以你取出for ... in ...部分并将它们重新组装成嵌套的for循环。然后取出if并将其嵌套在相应的for循环中;最后,你取第一部分(在本例中为(x, y))并嵌套在嵌套for结构的最深处。

if出现在多个"阶段时,这也很好。在列表理解中,例如:

#      X         A                 B               C               D
a = [(x, y)   for x in [1,2,3]   if x >= 2   for y in [3,1,4]   if x != y]

将(desugars)翻译为:

__tmp = []
for x in [1,2,3]:                     # A
    if x >= 2:                        # B
        for y in [3,1,4]:             # C
            if x != y:                # D
                __tmp.append((x, y))  # X

a = __tmp

再次......它与在部分之间散布的冒号的理解完全相同,并且内部部分正好在前面。 A B C D ...部分的顺序始终相同且永不改变;它只是X部分从后面移动到前面。