【问题标题】:Python - extending and filling list with zeros to match another listPython - 用零扩展和填充列表以匹配另一个列表
【发布时间】:2018-03-19 05:27:51
【问题描述】:

我有一个列表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 的位置,同样,作为与b 比较的结果,最后一个非零元素位于第五位.

最终输出总是len(b);如果开头的零太多而无法容纳所有a,则删除a 中的元素。

【问题讨论】:

  • 那么你的输入列表排序了吗?
  • @MartijnPieters 是的
  • 如果a[pos] == b[pos] 会发生什么,所以b 中有3.0
  • @MartijnPieters 然后 'pos' 将是第一个非零元素的位置
  • 如果ba 的“范围”之外有超过3 个元素会怎样?说b = [0.1, 2.1, 3.0, 3.5, 4.1, 5.8, 6.6, 7]?还是你基本上只将a[0]b 中的值对齐,然后匹配长度?

标签: python arrays list padding


【解决方案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)

【讨论】:

    【解决方案2】:

    使用二分法找到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)]
    

    二分法让您在 O(logN) 时间内找到点。

    另一种方法是使用生成器函数;循环 b 并 yield 0s 直到找到与 a[0] 相等或更大的值,然后 yield 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]
    

    【讨论】:

    • @johnhenry:啊,是的,我犯了一个错误,因为bisect_left 返回插入位置before
    • @johnhenry:全部修复。
    【解决方案3】:

    试试这个

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

    【讨论】:

      【解决方案4】:

      你可以用列表推导试试这个

      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)
      

      【讨论】:

        猜你喜欢
        • 2015-03-14
        • 1970-01-01
        • 2017-03-02
        • 1970-01-01
        • 2021-03-11
        • 1970-01-01
        • 2022-08-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多