1

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

问题:

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

假设我有 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。)

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

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

4

5 回答 5

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)
于 2013-04-10T03:38:59.643 回答
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(或 <3.3 for item in b: yield item)会将它们作为最终元素。

于 2013-04-10T03:50:27.413 回答
0

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

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
于 2013-04-10T08:48:14.093 回答
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]
于 2013-04-10T03:59:35.630 回答
0

Thanks all, and I get this solution inspired by @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]
于 2013-04-10T05:58:44.473 回答