在python中使用一些订单规则合并两个列表

时间:2013-04-10 03:27:39

标签: python

我不知道如何给出准确的标题,但这就是问题所在。

问题:

我想给出一个排名列表(想象一些顶级列表),并且已经保留了一些位置。

假设我有7个插槽[1, 2, 3, 4, 5, 6, 7, 8],有些已经保留了位置1,3,4,7,9。(因为我们只有8个插槽,所以保留位置9将意味着最后一个插槽。)

然后我剩下2,5,6个插槽,我必须用其他物体填充它们。

简化问题:

我有两个清单:

>>> a = [1, 3, 4, 7, 9]
>>> b = [object_x, object_y, object_z]

我想将它们合并到这个:

>>> c = [1, object_x, 3, 4, object_y, object_z, 7, 9]

(我们可以将'object_x'设为0。)

就是这样,只是想看看是否有一种优雅的方式来实现它。

(根据评论编辑整个问题。非常感谢你们。)

5 个答案:

答案 0 :(得分:2)

您可以使用生成器:

def merge(a, b):
    b_clone = b[:]

    for n in range(min(a), max(a) + 1):
        if n in a:
            yield n
        elif b_clone:
            yield b_clone.pop(0)

答案 1 :(得分:1)

我认为这涵盖了边缘情况,但我同意其他人认为必须有更好的方法来做到这一点。可能值得解释您尝试做的事情的背景。没有所有这些,可能有办法做到这一点。

def merge(a, b):
    b = list(b)
    a = iter(a)
    current = 1
    for item in a:
        while item != current:
            if b:
                yield b.pop(0)
            else:
                yield item
                yield from a  # <3.3 use `for item in a: yield item` instead.
                return
            current += 1
        yield item
        current += 1

根据您的规范,它似乎正常工作:

>>> print(list(merge([1, 3, 4, 7, 9], [0, 0, 0])))
[1, 0, 3, 4, 0, 0, 7, 9]
>>> print(list(merge([2, 4, 5], [1, 3])))
[1, 2, 3, 4, 5]

还不清楚在b中给出额外元素会发生什么 - 这会忽略它们,但在末尾添加yield from b(或者,&lt; 3.3 for item in b: yield item)会将它们作为最后的元素。

答案 2 :(得分:0)

这也应该有效:

>>>a = [2, 3, 5, 6, 7, 9]
>>>b = [0, 0, 0]
>>>length = len(a)
>>>i = 0

>>>while (i < length):
    if a[i] != i+1:
        a.insert(i, b.pop(0))
        length += 1
    i += 1

>>>print(a)
[0, 2, 3, 0, 5, 6, 7, 0, 9]

答案 3 :(得分:0)

谢谢大家,我得到了@jurgenreza启发的解决方案

>>> a = [1, 3, 4, 7, 9]
>>> b = [0, 0, 0]
>>> for i in a:
        b.insert(i - 1, i)

>>> print b
[1, 0, 3, 4, 0, 0, 7, 9]

答案 4 :(得分:0)

你可能最好避免首先进行这种合并。如果您事先知道有多少可能的等级,则可以将列表开始包含多个None,并且每次占用空格时,使用列表项分配而不是追加来设置。然后你的最终合并就像:

def merge(a, b):
   b = iter(b)
   for i,x in a: 
       if x is None:
          a[i] = next(b)

如果你如此倾向,你可以将这个whoe数据结构放入一个类中,这样你也可以检查你何时尝试覆盖占用位置(如果这是一个错误):

class Ranks:
    def __init__(self, size):
        self._list = [None] * size

    def __getitem__(self, position):
        return self._list[position]

    def __setitem__(self, position, val):
        if self._list[position] is None:
            raise ValueError('attempting to clobber existing rank data')
        self._list[position] = val