[英]How to make a list of lists from two lists
我正在嘗試完成以下任務,但到目前為止卻失敗了。 我有兩個排序的數字列表。 說
A = [5.8, 6.5, 7.6, 14.5, 18.1, 25.7, 26.4, 30.7, 30.9, 33.6, 38.6, 38.8, 39.2]
B = [9.0, 13.5, 22.5, 32.3 40.6, 43.2, 47.9, 54.2, 60.3, 63.0]
我要列出清單。 每個列表包含一個與B不同的值,以及A中該B值與列表中緊鄰其前一個值之間的所有值。 第一個列表僅包含小於B中的第一個值的所有內容。
因此,在這種情況下,列表列表應該開始
[[5.8, 6.5, 7.6, 9.0], [13.5], [14.5, 18.1, 22.5], [25.7, 26.4, 30.7. 30.9, 32.3]....]
如果更簡單/更快,我將對numpy代碼感到滿意。
我試過了:
[[*a, b] for b, a in itertools.groupby(A, lambda x: next(filter(lambda y: y >= x, B)))]
但它會錯過所有單例列表,並且我不確定在任何情況下它的速度如何。
我會這樣使用兩個指針,
i = 0
j= 0
ans = [] #contains the lists of lists
while j<len(B):
to_append = []
while i<len(A) and A[i]<=B[j]:
to_append.append(A[i])
i=i+1
to_append.append(B[j])
ans.append(to_append)
j=j+1
現在試試
您可以將heapq.merge
用於O(n + m)解決方案:
from itertools import chain, repeat
from heapq import merge
[*map(list, map(chain, map(iter, repeat(merge(A,B).__next__), B), zip(B)))]
# [[5.8, 6.5, 7.6, 9.0], [13.5], [14.5, 18.1, 22.5], [25.7, 26.4, 30.7, 30.9, 32.3], [33.6, 38.6, 38.8, 39.2, 40.6], [43.2], [47.9], [54.2], [60.3], [63.0]]
這將使用merge
按順序合並A和B。 接下來,使用iter的兩個參數形式在B的元素處進行拆分。不幸的是,這占用了拆分點,因此我們使用itertools.chain重新附加它們。
你可以做的
import numpy as np
A = [5.8, 6.5, 7.6, 14.5, 18.1, 25.7, 26.4, 30.7, 30.9, 33.6, 38.6, 38.8, 39.2]
B = [9.0, 13.5, 22.5, 32.3, 40.6, 43.2, 47.9, 54.2, 60.3, 63.0]
A = np.array(A)
B = np.hstack(([-np.inf], B))
result = [np.r_[np.extract((A>B[i]) & (A<= B[i+1]), A), B[i+1]] for i in range(len(B)-1)]
如果只需要列表,則可以執行以下操作:
result = [*map(lambda x : list(x), result),]
print(result)
# [[5.8, 6.5, 7.6, 9.0], [13.5], [14.5, 18.1, 22.5], [25.7, 26.4, 30.7, 30.9,
# 32.3], [33.6, 38.6, 38.8, 39.2, 40.6], [43.2], [47.9], [54.2], [60.3], [63.0]]
使用np.searchsorted解決O(N * logN)時間的問題。 首先,從B中的元素中查找元素的位置。其次,使用這些位置拆分數組A。 最后創建所需屬性的列表。
pos = np.searchsorted(A,B)
chunks = np.split(A, pos)
res = [np.hstack(ab) for ab in zip(chunks,B)]
這將生成所需的ndarray列表,您可以使用ndarray.tolist()方法將其轉換回列表:
res_list = list(map(np.ndarray.tolist, res))
作為純粹基於Numpy的方法(不那么重要),您可以將列表轉換為數組,然后執行以下操作:
In [43]: ind = (b[:,None] > a).sum(1)
In [44]: np.split(np.insert(a, ind, b), ind + np.arange(1, ind.size +1))
Out[44]:
[array([5.8, 6.5, 7.6, 9. ]),
array([13.5]),
array([14.5, 18.1, 22.5]),
array([25.7, 26.4, 30.7, 30.9, 32.3]),
array([33.6, 38.6, 38.8, 39.2, 40.6]),
array([43.2]),
array([47.9]),
array([54.2]),
array([60.3]),
array([63.]),
array([], dtype=float64)]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.