簡體   English   中英

如何從兩個列表中創建一個列表列表

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM