【问题标题】:Nested list comprehension with if statement带有 if 语句的嵌套列表推导
【发布时间】:2019-03-03 08:51:33
【问题描述】:

我正在努力理解嵌套列表的理解,并阅读了出色的解释 here

我正在翻译的问题是我的内部循环中有一个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}]

嵌套列表理解可能类似于

new_list = [if ??? y
               for x in nested_list
                   for y in x]

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

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

【问题讨论】:

  • 列表推导使用相同的嵌套顺序,从左到右。将if移动到同一个位置,不要放在值表达式中。
  • 然后你放弃了enumerate()函数调用,现在你没有一个d变量来测试。
  • @MartijnPieters 是的,第二次枚举中d 的丢失是我问题的症结所在。我会考虑一下您和 t@Jean-FrancoisFabre 的建议,谢谢。
  • @Sayse 我相信列表理解是一种更“pythonic”的做事方式,并且会提供更简洁、更易于维护的代码。
  • 在这种情况下,我强烈反对。

标签: python list if-statement list-comprehension


【解决方案1】:

你可以改写如下:

new_list = [y for x in nested_list for d, y in enumerate(x) if d == 1]

循环是“自然”的顺序,条件是最后。仅当 d==1 时才包含 y

一个可能的结果(因为字典没有排序):

[{'c': 3, 'd': 4}, {'c': 7, 'd': 8}]

请注意,在您的情况下,写起来更简单、更高效(O(n)O(n**2)):

new_list = [x[1] for x in nested_list]

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

new_list = [x[1] for x in nested_list if len(x)>1]

【讨论】:

  • 谢谢,这真的很有用,尤其是较短的x[1] 方式,因为在我的实际用例中,嵌套列表的长度将始终相同。
【解决方案2】:

当我从嵌套循环转到列表理解时,我失去了从 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 :

但是,您可以删除第一个 enumerate(),因为您不使用 c。您也可以删除第二个循环和enumerate(),因为您可以使用 indexing 代替:

new_list = [x[1] for x in nested_list]

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

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

new_list = [x[1] for x in nested_list if len(x) > 1]

【讨论】:

  • 谢谢,我只用了几个月的 Python,我还在学习,还没有意识到你可以让 if 语句保持原样。很清楚的解释,干杯
【解决方案3】:

你想要列表中每个数组的第二个元素,所以你可以这样做:

new_list = [nested_list[i][1] for i in range(len(nested_list))]

更好

new_list  = [x[1] for x in nested_list]

【讨论】:

    【解决方案4】:
    print ([ y for c, x in enumerate(nested_list) for d, y in enumerate(x) if d == 1])
    

    【讨论】:

    • 虽然这可能会回答作者的问题,但它缺少一些解释性词语和文档链接。如果没有围绕它的一些短语,原始代码 sn-ps 并不是很有帮助。您可能还会发现how to write a good answer 非常有帮助。请编辑您的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-08
    • 2021-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-08
    • 2017-01-13
    相关资源
    最近更新 更多