提问人:T S 提问时间:7/10/2023 最后编辑:T S 更新时间:7/10/2023 访问量:57
将列表字符串项中的列表与列表整数中的列表相乘
Multiply list in list string items with list in list integers
问:
我有 2 个列表:和list1
list2
list1
是列表中的列表,包含各种字符串 也是列表中的列表,由不同的整数值组成list2
两个列表的维度相同
我如何将每个字符串乘以每个整数以实现如下目的:list1
list2
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() 函数并使用 * 运算符,但没有任何效果
答:
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)
评论