[英]How to iterate over multiple lists of different lengths, but repeat the last value of a shorter list until the longest list is done?
In my Python 3 script, I am trying to make a combination of three numbers from three different lists based on inputs.在我的 Python 3 脚本中,我试图根据输入组合来自三个不同列表的三个数字。 If the lists are the same size, there is no issue with
zip
.如果列表大小相同,则
zip
没有问题。 However, I want to be able to input a single number for a specific list and the script to repeat that number until the longest list is finished.但是,我希望能够为特定列表输入一个数字,并且脚本可以重复该数字,直到最长的列表完成。 This can be done with
zip_longest
.这可以通过
zip_longest
来完成。 However, with fillvalue
it is not possible to have separate fill values for separate lists.但是,使用
fillvalue
无法为单独的列表设置单独的填充值。
Taking this simple script as an example:以这个简单的脚本为例:
from itertools import zip_longest
list1=[1]
list2=[4, 5, 6, 7, 8, 9]
list3=[2]
for l1, l2, l3 in zip_longest(list1, list2, list3):
print(l1, l2, l3)
This is the actual result:这是实际结果:
# 1 4 2
# None 5 None
# None 6 None
# None 7 None
# None 8 None
# None 9 None
And this would be the result that I want:这将是我想要的结果:
# 1 4 2
# 1 5 2
# 1 6 2
# 1 7 2
# 1 8 2
# 1 9 2
I already managed to do this specific task by manually creating different for loops and asking if a list is a constant or not, but zip_longest
is so close to exactly what I need that I wonder if I am missing something obvious.我已经设法通过手动创建不同的 for 循环并询问列表是否为常量来完成这项特定任务,但是
zip_longest
非常接近我所需要的,以至于我想知道我是否遗漏了一些明显的东西。
You could make use of logical or
operator to use the last element of the shorter lists:您可以使用逻辑
or
运算符来使用较短列表的最后一个元素:
from itertools import zip_longest
list1 = [1]
list2 = ["a", "b", "c", "d", "e", "f"]
list3 = [2]
for l1, l2, l3 in zip_longest(list1, list2, list3):
print(l1 or list1[-1], l2, l3 or list3[-1])
Out:出去:
1 a 2
1 b 2
1 c 2
1 d 2
1 e 2
1 f 2
You can make use of itertools.cycle
, which takes a list and returns a generator, looping through the contents of the list without stop.您可以使用
itertools.cycle
,它接受一个列表并返回一个生成器,不停地循环遍历列表的内容。
from itertools import cycle
list1 = [1]
list2 = [4, 5, 6, 7, 8, 9]
list3 = [2]
for l1, l2, l3 in zip(cycle(list1), list2, cycle(list3)):
print(l1, l2, l3)
Output: Output:
1 4 2
1 5 2
1 6 2
1 7 2
1 8 2
1 9 2
Note that we used the regular zip()
instead of zip_longest()
, otherwise cycle(list1)
and cycle(list3)
would keep generating values and we would encounter an infinite loop.请注意,我们使用常规
zip()
而不是zip_longest()
,否则cycle(list1)
和cycle(list3)
将继续生成值,我们会遇到无限循环。
If you just have one number you'd like to repeat, you can use repeat(x)
instead.如果您只想重复一个数字,则可以使用
repeat(x)
代替。
from itertools import repeat
x, y = 1, 2
list_ = [4, 5, 6, 7, 8, 9]
for l1, l2, l3 in zip(repeat(x), list_, repeat(y)):
print(l1, l2, l3)
The unique point with cycle
is that your lists will be repeated. cycle
的独特之处在于您的列表将被重复。 For example, the following set of lists will generate a different output from Meyer's solution:例如,以下列表集将生成与 Meyer 解决方案不同的 output:
list1 = [1, 3]
list2 = [4, 5, 6, 7, 8, 9]
list3 = [2]
Output: Output:
1 4 2
3 5 2
1 6 2
3 7 2
1 8 2
3 9 2
zipped = zip(list1 * len(list2), list2, list3 * len(list2))
for item in zipped:
print(item)
(1, 'a', 2)
(1, 'b', 2)
(1, 'c', 2)
(1, 'd', 2)
(1, 'e', 2)
(1, 'f', 2)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.