使用二分法查找第一個位置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'? –