Python - 使用零来扩展和填充列表以匹配另一个列表

时间:2017-10-07 15:48:39

标签: python arrays list padding

我有一个包含一些元素的列表a。我有另一个包含更多元素的列表b。我需要将a扩展为匹配b的大小,使用零来填充。在将出现的新列表中,原始a位于由b确定的位置,如下面的示例所示。
我的情况的一个小例子:

a = [3, 4, 5]

b = [1.2, 2.5, 3.7, 4.3, 5.1, 6.3, 7.3, 8.9]

我需要

[0, 0, 3, 4, 5, 0, 0, 0]

第一个非零元素在此处位于第三个位置,以匹配b变为等于或大于3的位置,类似地,最后一个非零元素位于第五个位置,作为与{的比较结果{1}}。

最终输出始终为b;如果一开始有太多的零符合len(b)的所有内容,则会删除a中的元素。

4 个答案:

答案 0 :(得分:1)

a = [3, 4, 5]
b = [1.2,2.5,3.7,4.3,5.1,6.3,7.3,8.9]

b.sort()  # Ensure they are sorted

start_zero_till = len(b) - len(a)
for i in range(len(b)):
    if a[0] < b[i]:
        start_zero_till = i
        break

revised_a = [0] * start_zero_till
revised_a.extend(a)
revised_a.extend([0] * (len(b) - len(revised_a)))

print(revised_a)

答案 1 :(得分:1)

使用二分法查找b中大于或等于a[0]的第一个位置,bisect module

import bisect

def zero_pad(a, b):
    pos = bisect.bisect(b, a[0])
    remainder = len(b) - len(a) - pos
    return ([0] * pos + a + [0] * remainder)[:len(b)]

Bisection可让您在O(logN)时间内找到该点。

另一种方法是使用发电机功能;循环b并生成0 s,直到找到与a[0]相等或更大的值,然后生成a直到用尽并返回零:

def zero_pad_gen(a, b, _sentinel=object()):
    a = iter(a)
    nexta = next(a, _sentinel)
    for bval in b:
        if nexta is _sentinel or bval < nexta:
            yield 0
        else:
            yield nexta
            nexta = next(a, _sentinel)

演示:

>>> a = [3, 4, 5]
>>> b = [1.2, 2.5, 3.7, 4.3, 5.1, 6.3, 7.3, 8.9]
>>> zero_pad(a, b)
[0, 0, 3, 4, 5, 0, 0, 0]
>>> list(zero_pad_gen(a, b))
[0, 0, 3, 4, 5, 0, 0, 0]

和边缘情况; b太短,从a

中删除了值
>>> zero_pad(a, b[:-4])
[0, 0, 3, 4]
>>> list(zero_pad_gen(a, b[:-4]))
[0, 0, 3, 4]

b匹配的第一个值:

>>> zero_pad([1, 2] + a, b)
[1, 2, 3, 4, 5, 0, 0, 0]
>>> list(zero_pad_gen([1, 2] + a, b))
[1, 2, 3, 4, 5, 0, 0, 0]

答案 2 :(得分:1)

试试这个

for i in b:
    if int(i) not in a:
        a.insert(b.index(i),0)

答案 3 :(得分:0)

你可以尝试使用列表推导

a = [3, 4, 5]
b = [1.2, 2.5, 3.7, 4.3, 5.1, 6.3, 7.3, 8.9]
num=[c for c,e in enumerate(b) if e>=a[0]][0]
c=[0 for e in range(num)]+a+[0 for e in range(len(b)-num-len(a))]
print(c)