【问题标题】:Iterate over two lists with different lengths迭代两个不同长度的列表
【发布时间】:2017-10-15 11:48:36
【问题描述】:

我有 2 个长度不同的数字列表,例如:

list1 = [1, 2, -3, 4, 7]
list2 = [4, -6, 3, -1]

我需要用函数遍历这些:

final_list = []
for index in range(???):
    if list1[index] < 0:
        final_list.insert(0, list1[index])
    elif list1[index] > 0:
        final_list.insert(len(final_list), list1[index])
    if list2[index] < 0:
        final_list.insert(0, list2[index])
    elif list2[index] > 0:
        final_list.insert(len(final_list), list2[index])
return final_list

但不知道如何处理范围,因为如果我使用 max 长度,较短的列表将变得“超出范围”。关于如何克服这个问题或如何改变我的功能有什么想法吗?

【问题讨论】:

  • 你想完成什么?
  • 你能解释一下输出应该是什么吗?
  • for item1, item2 in itertools.zip_longest(list1, list2)?
  • itertools使用zip_longest
  • 请解释一下你的逻辑?

标签: python list loops


【解决方案1】:

在您的情况下,您可能应该只检查索引是否比序列长:

list1 = [1, 2, -3, 4, 7]
list2 = [4, -6, 3, -1]

final_list = []
for index in range(max(len(list1), len(list2))):
    if index < len(list1):
        if list1[index] < 0:
            final_list.insert(0, list1[index])
        elif list1[index] > 0:
            final_list.insert(len(final_list), list1[index])

    if index < len(list2):
        if list2[index] < 0:
            final_list.insert(0, list2[index])
        elif list2[index] > 0:
            final_list.insert(len(final_list), list2[index])

print(final_list)
# [-1, -3, -6, 1, 4, 2, 3, 4, 7]

或者使用itertools.zip_longest(或者在python-2.x上使用itertools.izip_longest)并检查一些填充值(即None):

import itertools

list1 = [1, 2, -3, 4, 7]
list2 = [4, -6, 3, -1]

final_list = []
for item1, item2 in itertools.zip_longest(list1, list2, fillvalue=None):
    if item1 is None:
        pass
    elif item1 < 0:
        final_list.insert(0, item1)
    elif item1 > 0:
        final_list.append(item1)

    if item2 is None:
        pass
    elif item2 < 0:
        final_list.insert(0, item2)
    elif item2 > 0:
        final_list.append(item2)

但是,当它们是 == 0 时,您的方法会跳过项目,这可能是一个疏忽,但您应该检查它在使用零时是否正确。

你也经常使用insert。最后一个elifs 可以改用final_list.append(item1)(或item2),就像我在第二个示例中所做的那样。

在这种情况下,item1item2 的处理是相同的,因此您可以使用另一个循环:

import itertools

list1 = [1, 2, -3, 4, 7]
list2 = [4, -6, 3, -1]

final_list = []
for items in itertools.zip_longest(list1, list2, fillvalue=None):
    for item in items:
        if item is None:
            pass
        elif item < 0:
            final_list.insert(0, item)
        elif item > 0:
            final_list.append(item)

【讨论】:

    【解决方案2】:

    您可以使用itertools.zip_longest()(如果使用Python 2,则为itertools.izip_longest())处理列表中的相邻项目,以生成一系列配对项目。对于长度不匹配的列表,将使用 None 填充对。

    然后,您可以通过展平配对项的序列并过滤掉 None 值(在您的情况下为 0 值)来简化循环主体中的代码。这就是下面的生成器表达式所做的。

    然后,如果分别大于或小于零,只需将值附加或插入到 final_list 中即可。

    在代码中:

    from itertools import zip_longest
    
    final_list = []
    for value in (i for pair in zip_longest(list1, list2) for i in pair if i):
        if value > 0:
            final_list.append(value)
        else:
            final_list.insert(0, value)
    
    print(final_list)
    
    [-1, -3, -6, 1, 4, 2, 3, 4, 7]

    请注意,这将过滤掉列表中可能存在的任何零值。如果您想保留这些,请修改生成器表达式以仅过滤掉 None 值:

    (i for pair in zip_longest(list1, list2)
        for i in pair if i is not None)
    

    并修改循环体以将0 插入到final_list 中应插入的任何位置。

    【讨论】:

      【解决方案3】:

      itertools.zip_longest(*iterables, fillvalue=None) 将为您完成这项工作:

      如果iterables长度不均匀,则用fillvalue填充缺失值。

      对于您的示例列表,这将产生:

      >>> import itertools
      >>> list1 = [1, 2, -3, 4, 7]
      >>> list2 = [4, -6, 3, -1]
      
      >>> for combination in itertools.zip_longest(list1, list2):
          print(combination)
      
      (1, 4)
      (2, -6)
      (-3, 3)
      (4, -1)
      (7, None)
      

      如果您只想使用两个列表中存在的值,请使用内置的zip()

      当最短的输入迭代用完时,迭代器停止。

      >>> for combination in zip(list1, list2):
          print(combination)
      
      (1, 4)
      (2, -6)
      (-3, 3)
      (4, -1)
      

      【讨论】:

        猜你喜欢
        • 2018-02-02
        • 1970-01-01
        • 2022-01-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-20
        • 1970-01-01
        相关资源
        最近更新 更多