我有两个列表:
A = ["a","b","c","d","e","f","g","h","i"]
B = [1,2,3]
A比B长3倍,因此我想使用它们将它们匹配在一起,如下所示:
C = [("a",1"),("b",1"),("c",1"),
("d",2),("e",2),("f",2),
("g",3),("h",3),("i",3)]
因此,A的前三个元素与B的第一个元素匹配,A的下三个元素与B的第二个元素匹配,依此类推。
富特莫尔,这是一个非常简单的例子。当一个列表比另一个列表大而不是整数时,我也会对如何最好地公平分配元素感兴趣。例如,我的两个列表长10001和511个元素,所以第一个比第二个大〜19.57。最好是我想使用两个列表中的每个元素。
答案 0 :(得分:3)
假设A
的长度是B
的倍数,您可以轻松做到
>>> scale = len(A) // len(B)
>>> [(a, B[i // scale]) for i, a in enumerate(A)]
[('a', 1),
('b', 1),
('c', 1),
('d', 2),
('e', 2),
('f', 2),
('g', 3),
('h', 3),
('i', 3)]
工作原理:
k
的值,使len(A) == k * len(B)
A
,然后使用k
通过将当前索引除以B
来确定选择哪个值{1>
如果长度不是整数倍,它将抛出
IndexError: list index out of range
您可以通过计算scale
来规避这一点
scale = len(A) // len(B) * len(B)
例如,
A = ["a", "b", "c", "d", "e", "f", "g", "h"]
B = [1, 2, 3]
>>> scale = len(A) // len(B) * len(B)
>>> [(a, B[i // scale]) for i, a in enumerate(A)]
[('a', 1),
('b', 1),
('c', 1),
('d', 1),
('e', 1),
('f', 1),
('g', 2),
('h', 2)]
这是使用itertools
repeat
和chain.from_iterable
的功能方法。
>>> from itertools import repeat, chain
>>> list(zip(A, chain.from_iterable(zip(*repeat(B, scale)))))
[('a', 1),
('b', 1),
('c', 1),
('d', 2),
('e', 2),
('f', 2),
('g', 3),
('h', 3),
('i', 3)]
答案 1 :(得分:1)
在这里,我认为第一个列表较长。
这是简单的方法:
rep = len(A) // len(B)
ia = iter(A)
C = [(next(ia), b) for b in B for i in range(rep)]
C.extend((a, B[-1]) for a in ia) # in case len(A) is not an exact multiple of len(B)
答案 2 :(得分:0)
您可以使用grouper
文档中的itertools
recipe(或从more_itertools
中导入)。
食谱:
from itertools import zip_longest
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return zip_longest(*args, fillvalue=fillvalue)
应用程序:
>>> from more_itertools import grouper
>>> A = ["a","b","c","d","e","f","g","h","i"]
>>> B = [1,2,3]
>>> [(x, i) for vals, i in zip(grouper(A, len(B)), B) for x in vals]
[('a', 1),
('b', 1),
('c', 1),
('d', 2),
('e', 2),
('f', 2),
('g', 3),
('h', 3),
('i', 3)]
答案 3 :(得分:0)
您还可以尝试使用zip()
并用自己的列表理解重复B
:
>>> A = ["a","b","c","d","e","f","g","h","i"]
>>> B = [1,2,3]
>>> list(zip(A, (y for x in B for y in len(B) * [x])))
[('a', 1), ('b', 1), ('c', 1), ('d', 2), ('e', 2), ('f', 2), ('g', 3), ('h', 3), ('i', 3)]
还建议不要对len(B) * 3
进行硬编码,而使用scale = len(A) // len(B)
来获取比例分布,如@coldspeed's答案所示
答案 4 :(得分:0)
您还可以将A
分组为子列表列表,每个子列表的长度为B
:
A = ["a","b","c","d","e","f","g","h","i"]
B = [1,2,3]
_b = len(B)
new_a = [A[i:i+_b] for i in range(0, len(A), _b)]
final_result = [(c, i) for a, i in zip(new_a, B) for c in a]
输出:
[('a', 1), ('b', 1), ('c', 1), ('d', 2), ('e', 2), ('f', 2), ('g', 3), ('h', 3), ('i', 3)]