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

就是这样,只是想看看是否有一个优雅的方法来实现这个

(根据评论编辑整个问题。非常感谢大家。

您可以使用生成器:

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)

我相信这涵盖了边缘情况,然而,我同意其他人的观点,似乎一定有更好的方法来做到这一点。也许有必要解释一下你正在尝试做的事情的背景。也许有一种不需要这些的方法。

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(或,<3.3 for item in b: yield item)会将它们作为最后的元素。

这应该也可以:

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

谢谢大家,我的灵感来自于@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]

一开始就避免进行这种合并可能会更好。如果你事先知道有多少个可能的排名,你可以从包含None的列表开始,并且每次占用一个空间时,使用列表项分配而不是附加来设置它。那么最终的合并就像这样简单:

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

如果你愿意,你可以把这整个数据结构放到一个类中,这也允许你,例如,检查当你试图覆盖一个被占用的位置(如果这将是一个错误):

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

最新更新