【问题标题】:How to iterate over multiple lists of different lengths, but repeat the last value of a shorter list until the longest list is done?如何迭代多个不同长度的列表,但重复较短列表的最后一个值,直到完成最长列表?
【发布时间】:2021-03-18 18:21:15
【问题描述】:

在我的 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 与我所需要的非常接近,以至于我想知道我是否遗漏了一些明显的东西。

【问题讨论】:

标签: python python-3.x list iterator


【解决方案1】:

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

【讨论】:

    【解决方案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
    

    【讨论】:

      【解决方案3】:
      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)
      

      【讨论】:

        猜你喜欢
        • 2011-06-16
        • 2017-10-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-02
        • 2022-01-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多