如何从两个列表中创建一个列表列表

时间:2019-07-15 19:58:01

标签: python numpy

我正在尝试完成以下任务,但到目前为止仍失败。我有两个排序的数字列表。说

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)))]

但是它会丢失所有单例列表,并且我不确定在任何情况下它有多快。

5 个答案:

答案 0 :(得分:2)

我会使用两个这样的指针

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

立即尝试

答案 1 :(得分:2)

您可以将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重新附加它们。

答案 2 :(得分:1)

您可以做到,

public setEdt(date: String): void {
calendarEditText.setText(date)
}

,如果您只想列出,则可以执行以下操作:

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)]

答案 3 :(得分:1)

使用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))

答案 4 :(得分:0)

作为纯粹基于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)]