使用二分法查找第一个位置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
和屈服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]
那么你的输入列表是否被排序? –
@MartijnPieters yes – johnhenry
如果'a [pos] == b [pos]'会发生什么,所以'b'中有'3.0'? –