【问题标题】:How to do this list如何做这个清单
【发布时间】:2019-08-21 08:50:19
【问题描述】:

假设我从列表开始:

list1 = [['a', '1', '2'], ['b', '1'], ['c'], ['d']]

和元组:

b = (1, 2, 3, 4)

现在我想得到一个类似的列表:

c = [['a', '1', '2'], ['b', '1', '1'], ['b', '1', '2'], ['b', '1', '3'], ['b', '1', '4'], ['c'], ['d']]

所以b 的每个部分都扩展了b 所在的旧嵌套列表的新副本。

所以基本上我想要的是这样的:

c = [i + [j] for j in b if "b" in i else i for i in a]            (1)

遗憾的是,这不起作用。

所以我尝试了:

c = [[i + [j] for j in b] if "b" in i else i for i in a]

这给了我:

[['a', '1', '2'], [['b', '1', 1], ['b', '1', 2], ['b', '1', 3], ['b', '1', 4]], ['c'], ['d']]

然后我尝试再次拆分它,但我没有成功。

我最好的尝试是:

[i[x] if type(i[0]) is list else i for i in c for x in range(len(i))]

有没有办法让 (1) 正常工作或让我得到我想要的结果的列表?我有点卡住了。可能这很容易,但我看不到路。

【问题讨论】:

  • 与推导有关似乎有点复杂,因为您希望每次迭代添加多个项目,所以我猜您要么在之后展平列表,要么强制执行,使用 list.append()如果没有“b”或多个list.append(),如果有“b”。

标签: python python-3.x list list-comprehension


【解决方案1】:

我会避免对这种复杂的东西进行列表推导:

list1 = [['a', '1', '2'], ['b', '1'], ['c'], ['d']]

b = (1, 2, 3, 4)

new_list = []
for i in list1:
    if 'b' in i:
        extended = [i + [str(j)] for j in b]
        new_list += extended
    else:
        new_list.append(i)

【讨论】:

  • 这个技巧非常好!我只是被困在训练理解中,但我想有时使用它们会让生活变得更难:D
  • 是的,Python 作为一种函数式语言并不是很好。在其他语言中,您可以使用 flatMap 之类的东西,这使这变得微不足道。
【解决方案2】:

如果你真的想要一个列表理解,你可以试试

list1 = [['a', '1', '2'], ['b', '1'], ['c'], ['d']]
b = (1, 2, 3, 4)
c = list1.copy()  # to ensure we don't modify list1
c[1:2] = [list1[1] + [i] for i in b]

【讨论】:

  • 而不是使用像 c[1:2] 这样的硬编码索引,我建议您使用动态方式在包含“b”的列表中查找对象的索引。这会将第 4 行更改为 c[b_index:b_index+1] = [list1[b_index] + [i] for i in b]
  • 我没有在问题中提到它,那是我的错,但我不知道带有 b 的列表在哪里开始,如果有多个带有 b 的嵌套列表,那么应该全部对待。但我猜丹的回答确实能起到作用,只是不会让人理解。还是谢谢!
【解决方案3】:
list1 = [['a', '1', '2'], ['b', '1'], ['c'], ['d']]
b = (1, 2, 3, 4)

b_index = list(filter(lambda index: 'b' in list1[index], range(len(list1))))[0] # searx for list which contains b

list1[b_index] = [list1[b_index]+[item] for item in b]
print (list1)

输出:

[['a', '1', '2'], [['b', '1', 1], ['b', '1', 2], ['b', '1', 3], ['b', '1', 4]], ['c'], ['d']]

【讨论】:

    【解决方案4】:

    您想要的缺失步骤 - 拆分 (1) 的结果将是:

    reduce(lambda x, y: (x if isinstance(x[0], list) else [x]) +
                        (y if isinstance(y[0], list) else [y]),
           [[i + [str(j)] for j in b] if "b" in i else i for i in a])
    

    或者更易读:

    def unnest(x):
        return x if isinstance(x[0], list) else [x]
    
    # Your original (1) attempt (just adding str):
    c = [[i + [str(j)] for j in b] if "b" in i else i for i in a]
    
    result = reduce(lambda x, y: unnest(x) + unnest(y), c)
    

    但正如 Dan 所建议的,在这种情况下避免列表理解可能更具可读性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多