简体   繁体   English

迭代两个不同长度的列表

[英]Iterate over two lists with different lengths

I have 2 lists of numbers that can be different lengths, for example: 我有2个不同长度的数字列表,例如:

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

I need to iterate over these with the function: 我需要使用函数迭代这些:

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

but can't figure out how to deal with the range as the shorter list will become "out of range" if I use the max length. 但无法弄清楚如何处理范围,因为如果我使用max长度,较短的列表将变得“超出范围”。 Any thoughts on how to overcome this or how to change my function? 有关如何克服这个或如何改变我的功能的任何想法?

itertools.zip_longest(*iterables, fillvalue=None) will do the job for you: itertools.zip_longest(*iterables, fillvalue=None)将为您完成工作:

If the iterables are of uneven length, missing values are filled-in with fillvalue . 如果迭代的长度不均匀,则使用fillvalue填充缺失值。

For your example lists, this will yield: 对于您的示例列表,这将产生:

>>> 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)

If you only want to use as many values as are present in both lists, use the built-in zip() : 如果您只想使用两个列表中存在的值,请使用内置的zip()

The iterator stops when the shortest input iterable is exhausted. 当最短输入可迭代用尽时,迭代器停止。

>>> for combination in zip(list1, list2):
    print(combination)

(1, 4)
(2, -6)
(-3, 3)
(4, -1)

You can process adjacent items from the lists by using itertools.zip_longest() ( itertools.izip_longest() if using Python 2) to produce a sequence of paired items. 可以通过使用处理从列表中相邻的项目itertools.zip_longest() itertools.izip_longest()以产生成对的项的顺序,如果使用Python 2)。 Pairs will be padded with None for lists of mismatched length. 对于不匹配长度的列表,对将填充None

Then you can simplify the code in the body of the loop by flattening the sequence of paired items and filtering out the None values, and in your case, 0 values. 然后,您可以通过展平配对项的序列并过滤掉None值来简化循环体中的代码,在您的情况下,过滤掉0值。 That's what the generator expression below does. 这就是下面的生成器表达式。

Then it's just a matter of appending or inserting values into final_list if greater or less than zero respectively. 然后,如果分别大于或小于零,则只需将值附加或插入到final_list

In code: 在代码中:

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]

Notice that this will filter out any zero values that might be present in the lists. 请注意,这将过滤掉列表中可能存在的任何零值。 If you want to keep these then modify the generator expression to filter out the None values only: 如果要保留这些,请修改生成器表达式以仅过滤掉None值:

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

and modify the body of the loop to insert the 0 wherever it should go in final_list . 并修改循环体以在final_list任何位置插入0

In your case you should probably just check if the index is longer than the sequence: 在您的情况下,您应该只检查索引是否比序列长:

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]

Or use itertools.zip_longest (or itertools.izip_longest on python-2.x) and check for some fillvalue (ie None ): 或者使用itertools.zip_longest (或python-2.x上的itertools.izip_longest )并检查一些fillvalue(即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)

However your approach skips items when they are == 0 , that's probably an oversight but you should check that it's working correct with zeros. 但是当你的方法是== 0 ,你的方法会跳过这些项目,这可能是一种疏忽,但是你应该用零来检查它是否正常工作。

Also you use insert a lot. 你也经常使用insert The last elif s could instead use final_list.append(item1) (or item2 ), like I did in the second example. 最后一个elif可以改为使用final_list.append(item1) (或item2 ),就像我在第二个例子中所做的那样。

In this case the handling for item1 and item2 is identical, so you could use another loop: 在这种情况下, 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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM