【问题标题】:Python append lists in a specific wayPython以特定方式附加列表
【发布时间】:2017-10-15 17:44:50
【问题描述】:

我知道我实际上可以合并两个列表(在 Python 2.7 中),如下所示

list1 = ['one', 'two', 'three', 'four', 'five']
list2 = ['A', 'B', 'C', 'D', 'E']
merged = list1 + list2
print merged
# ['one', 'two', 'three', 'four', 'five', 'A', 'B', 'C', 'D', 'E']

问题是,我想在 list1 的每两个之后插入一个 list2。示例:

list1 = ['one', 'two', 'three', 'four', 'five']
list2 = ['A', 'B', 'C', 'D', 'E']
after 2 of list1:
     add 1 of list2
print merged
# ['one', 'two', 'A', 'three', 'four', 'B', 'five', 'six', 'C', 'seven', 'eight', 'D', 'nine', 'ten']

任何帮助将不胜感激!

【问题讨论】:

  • 这个'seven', 'eight'应该如何生成?

标签: python list append


【解决方案1】:

您可以尝试izip_longest 用于 python 2.7(或zip_longest 用于 python 3+),假设任一列表中的额外元素将附加到结果中:

from itertools import izip_longest

[y for x in izip_longest(list1[::2], list1[1::2], list2) for y in x if y is not None]
# ['one', 'two', 'A', 'three', 'four', 'B', 'five', 'C', 'D', 'E']

如果您想删除未配对的元素,请使用zip

[y for x in zip(list1[::2], list1[1::2], list2) for y in x]
# ['one', 'two', 'A', 'three', 'four', 'B']

【讨论】:

  • 这个问题特别提到了python-2.7,所以你可能应该使用itertools.izip_longest(或者至少提到它)。否则很好的答案:)
【解决方案2】:

您可以使用enumeratelist.insert

>>> l1 = ['A', 'B', 'C', 'D']
>>> l2 = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten']
>>> l3 = l2[:]  # makes a copy
>>> for idx, item in enumerate(l1):
...     l3.insert((idx*3+2), item)
>>> l3
['one', 'two', 'A', 'three', 'four', 'B', 'five', 'six', 'C', 'seven', 'eight', 'D', 'nine', 'ten']

【讨论】:

    【解决方案3】:

    在这种情况下,使用原始迭代器可以生成干净的代码,您可以在迭代器上调用 next 以获取下一个值,然后将其附加到结果中,因此列表创建非常直观:

    list1 = ['one', 'two', 'three', 'four', 'five']
    list2 = ['A', 'B', 'C', 'D', 'E']
    iter_list1 = iter(list1)
    iter_list2 = iter(list2)
    
    final = []
    try: #broken when one of the iterators runs out (and StopIteration is raised)
        while True:
            final.append(next(iter_list1))
            final.append(next(iter_list1))
    
            final.append(next(iter_list2))
    except StopIteration:
        pass
    #one will already be empty, add the remaining elements of the non-empty one to the end of the list.
    final.extend(iter_list1)
    final.extend(iter_list2)
    
    print(final)
    

    【讨论】:

    • 为什么不直接遍历zip(iter_list1, iter_list1, iter_list2)
    • 因为我不喜欢那个充满激情的成语。它是唯一一种语法对迭代器和可迭代对象都有效但仅对迭代器有效的习惯用法。
    • 只要像你一样以x = iter(x)开头,那就不是问题
    • 只有当 list1 有奇数个元素并在 list2 之前结束时,您的方法才会删除最后一个元素。 (在这种情况下,"five" 无处可见)相信我,并行 zip 的东西只是麻烦......
    • @Chris_Rands 我想成为一名教师而不是一名优秀的程序员。我发布的那种循环对于初学者来说非常容易操作和使用,没有任何晦涩的问题。一旦有人对 python 和迭代器感到满意,并且正在寻找编写更高效/更短/更易于阅读的代码的方法,并了解zip 的期望值,那么绝对会去做 - 那不是我的听众写作。
    【解决方案4】:
    >>> from operator import add
    >>> reduce(add,zip(list1[::2], list1[1::2], list2))
    ('one', 'two', 'A', 'three', 'four', 'B')
    

    注意 - 这将删除尾随元素。

    说明:

    你可以使用像l这样的列表切片作为列表l[low:high:step]来获取,

    >>> list1[::2]
    ['one', 'three', 'five']
    >>> list1[1::2]
    ['two', 'four']
    

    这样,

    >>> zip(list1[::2], list1[1::2])
    [('one', 'two'), ('three', 'four')]
    

    因此,

    >>> zip(list1[::2], list1[1::2], list2)
    [('one', 'two', 'A'), ('three', 'four', 'B')]
    >>> reduce(add,zip(list1[::2], list1[1::2], list2))
    ('one', 'two', 'A', 'three', 'four', 'B')
    

    【讨论】:

      猜你喜欢
      • 2021-08-17
      • 1970-01-01
      • 1970-01-01
      • 2016-06-25
      • 2019-05-10
      • 2016-11-21
      • 1970-01-01
      • 1970-01-01
      • 2015-08-10
      相关资源
      最近更新 更多