如何迭代多个不同长度的列表,但重复较短列表的最后一个值,直到完成最长列表?

在我的 Python 3 脚本中,我试图根据输入组合来自三个不同列表的三个数字。如果列表大小相同,则zip. 但是,我希望能够为特定列表输入单个数字,并且脚本可以重复该数字,直到最长的列表完成。这可以通过zip_longest. 但是,fillvalue对于单独的列表,不可能有单独的填充值。

以这个简单的脚本为例:

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)

这是实际结果:

# 1    4 2
# None 5 None                                                        
# None 6 None                                                         
# None 7 None
# None 8 None
# None 9 None  

这将是我想要的结果:

# 1 4 2
# 1 5 2                                                        
# 1 6 2                                                         
# 1 7 2
# 1 8 2
# 1 9 2                                                        
 

我已经设法通过手动创建不同的 for 循环并询问列表是否为常量来完成此特定任务,但zip_longest与我所需要的非常接近,我想知道我是否遗漏了一些明显的东西。

回答

您可以使用逻辑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])

出去:

1 a 2
1 b 2
1 c 2
1 d 2
1 e 2
1 f 2


回答

您可以使用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)

输出:

1 4 2
1 5 2
1 6 2
1 7 2
1 8 2
1 9 2

请注意,我们使用了常规zip()的替代zip_longest(),否则cycle(list1)cycle(list3)会继续产生价值,我们会遇到一个无限循环。

如果您只想重复一个数字,则可以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)

独特的一点cycle是您的列表将被重复。例如,以下列表集将生成与 Meyer 解决方案不同的输出:

list1 = [1, 3]
list2 = [4, 5, 6, 7, 8, 9]
list3 = [2]

输出:

1 4 2
3 5 2
1 6 2
3 7 2
1 8 2
3 9 2


以上是如何迭代多个不同长度的列表,但重复较短列表的最后一个值,直到完成最长列表?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>