将列表字符串项中的列表与列表整数中的列表相乘

Multiply list in list string items with list in list integers

提问人:T S 提问时间:7/10/2023 最后编辑:T S 更新时间:7/10/2023 访问量:57

问:

我有 2 个列表:和list1 list2

list1是列表中的列表,包含各种字符串 也是列表中的列表,由不同的整数值组成list2

两个列表的维度相同

我如何将每个字符串乘以每个整数以实现如下目的:list1list2

list1 = [['ABC','DEF'],['GHI','JKL'],['MNO','PQR']]
list2 = [[2, 2], [3, 3], [4, 4]]


result = [['ABC', 'ABC', 'DEF', 'DEF'], ['GHI', 'GHI', 'GHI', 'JKL', 'JKL', 'JKL'], ...]

谢谢

我已经尝试了 zip() 函数并使用 * 运算符,但没有任何效果

Python 列表 嵌套列表

评论

0赞 Julien 7/10/2023
“我已经试过了......但没有任何效果“ 如何提问最小的可重复示例
0赞 Xiaomin Wu 7/10/2023
在演示中,list1 和 list2 的长度不同。

答:

1赞 Zero 7/10/2023 #1

期望中的子列表可以具有不同的值。我编码了这个:list2

list1 = [['ABC','DEF'],['GHI','JKL'],['MNO','PQR']]
list2 = [[2, 2], [3, 3], [4, 4], [1, 1]]

combined = []
for sublist1, sublist2 in zip(list1, list2):
    sublist = []
    for elem1, elem2 in zip(sublist1, sublist2):
        sublist.extend([elem1]* elem2)

    combined.append(sublist)

print(combined)

结果:

[['ABC', 'ABC', 'DEF', 'DEF'], ['GHI', 'GHI', 'GHI', 'JKL', 'JKL', 'JKL'], ['MNO', 'MNO', 'MNO', 'MNO', 'PQR', 'PQR', 'PQR', 'PQR']]
0赞 Julien 7/10/2023 #2

这是一个简单的 1 行:

[[s for s, n in zip(l1, l2) for _ in range(n)] for l1,l2 in zip(list1, list2)]
0赞 Ξένη Γήινος 7/10/2023 #3

@Zero 的代码可以简化为以下列表理解 oneliner:

list1 = [['ABC','DEF'],['GHI','JKL'],['MNO','PQR']]
list2 = [[2, 2], [3, 3], [4, 4], [1, 1]]
[[i for i, j in zip(a, b) for _ in range(j)] for a, b in zip(list1, list2)]

性能:

In [153]: %timeit [[i for i, j in zip(a, b) for _ in range(j)] for a, b in zip(list1, list2)]
3.86 µs ± 234 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

In [154]: def func(list1, list2):
     ...:     combined = []
     ...:     for sublist1, sublist2 in zip(list1, list2):
     ...:         sublist = []
     ...:         for elem1, elem2 in zip(sublist1, sublist2):
     ...:             sublist.extend([elem1]* elem2)
     ...:
     ...:         combined.append(sublist)
     ...:     return combined

In [155]: %timeit func(list1, list2)
2.76 µs ± 135 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

我很惊讶地发现我的方法变慢了。

我想出了另一种方法,但它不知何故更慢:

from itertools import chain

[list(chain(*([i]*j for i, j in zip(a, b)))) for a, b in zip(list1, list2)]
In [158]: %timeit [list(chain(*([i]*j for i, j in zip(a, b)))) for a, b in zip(list1, list2)]
4.76 µs ± 78.9 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

所以我想出了我能想到的最聪明的方法,但它仍然很慢:

from functools import reduce
from operator import iconcat

def repeat_elements(a, b):
    return reduce(iconcat,([i]*j for i, j in zip(a, b)),[])

list(map(repeat_elements, list1, list2))
In [169]: %timeit list(map(repeat_elements, list1, list2))
3.86 µs ± 90.1 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

不知何故,我的聪明方法都不如愚蠢的直接方法。这真是令人羞愧。但我喜欢这个小小的练习。

-1赞 Xiaomin Wu 7/10/2023 #4
list1 = [['ABC','DEF'],['GHI','JKL'],['MNO','PQR']]
list2 = [[2, 2], [3, 3], [4, 4]]
res = []
for l1, l2 in zip(list1, list2):
    res.append([])
    for t1, t2 in zip(l1, l2):
        res[-1].extend([t1]*t2)
print(res)

评论

0赞 Itération 122442 7/12/2023
避免只回答代码并提供解释。
0赞 moken 7/17/2023
答案需要支持信息 您的答案可以通过其他支持信息进行改进。请编辑以添加更多详细信息,例如引文或文档,以便其他人可以确认您的答案是正确的。您可以在帮助中心找到有关如何写出好答案的更多信息。