使用if语句嵌套列表理解

sla*_*ine 4 python if-statement list-comprehension list

我试图了解嵌套列表理解并阅读了这里的优秀解释.

我正在翻译的问题是if我的内循环中有一个子句,我无法看到如何将这个应用于该func()步骤,因为enumerate()当我从嵌套循环到列表理解时我失去了计数器.

nested_list = [[{'a': 1, 'b': 2}, {'c': 3, 'd': 4}], [{'a': 5, 'b': 6}, {'c': 7, 'd': 8}]]
new_list = []
for c, x in enumerate(nested_list):
    for d, y in enumerate(x):
        if d == 1:
            new_list.append(y)
print(new_list)
[{'c': 3, 'd': 4}, {'c': 7, 'd': 8}]
Run Code Online (Sandbox Code Playgroud)

嵌套列表理解可能看起来像

new_list = [if ??? y
               for x in nested_list
                   for y in x]
Run Code Online (Sandbox Code Playgroud)

...但是我无法看到/想到如何获得该子句,因为我在嵌套列表理解下没有计数器.

有没有办法实现这一点,还是应该坚持嵌套循环方法?

Jea*_*bre 7

您可以按如下方式重写:

new_list = [y for x in nested_list for d, y in enumerate(x) if d == 1]
Run Code Online (Sandbox Code Playgroud)

循环处于"自然"顺序,条件最终.y仅包括d==1

一个可能的结果(因为dicts没有订购):

[{'c': 3, 'd': 4}, {'c': 7, 'd': 8}]
Run Code Online (Sandbox Code Playgroud)

请注意,在您的情况下,它更简单,更有效(O(n)vs O(n**2))编写:

new_list = [x[1] for x in nested_list]
Run Code Online (Sandbox Code Playgroud)

唯一的区别是如果x太短,后面的代码就会破坏,所以可能是测试长度:

new_list = [x[1] for x in nested_list if len(x)>1]
Run Code Online (Sandbox Code Playgroud)


Mar*_*ers 5

enumerate()因为我失去了从嵌套循环到列表理解时得到的计数器。

那你为什么把它扔掉呢?列表理解仍然可以使用与for循环相同的迭代器。

我的内循环中有一个 if 子句,但我不知道如何应用它

只要把它放在同一个地方就可以了。for列表推导式对于循环和过滤器都遵循相同的嵌套顺序if;您可以通过删除冒号:并将调用中的部分移到.append(...)前面来直接映射循环:

new_list = [y   # from new_list.append(y)
    for c, x in enumerate(nested_list)   # removed the :
        for d, y in enumerate(x)         # removed the :
            if d == 1]                   # removed the :
Run Code Online (Sandbox Code Playgroud)

但是,您可以删除第一个enumerate(),因为您不使用c. 您还可以删除第二个循环 和enumerate(),因为您可以改用索引

new_list = [x[1] for x in nested_list]
Run Code Online (Sandbox Code Playgroud)

您不需要循环遍历x此处的所有值,这不是获取该值的一种非常有效的方法。

如果您的问题是x列表可能更短并且索引 1 处没有元素,请首先按长度过滤这些嵌套列表:

new_list = [x[1] for x in nested_list if len(x) > 1]
Run Code Online (Sandbox Code Playgroud)