我有两个看起来像
的元素列表a=[['10', 'name_1'],['50','name_2'],['40','name_3'], ..., ['80', 'name_N']]
b=[(10,40),(40,60),(60,90),(90,100)]
a
包含一组数据,b
定义了一些时间间隔,我的目的是创建一个列表c
,其列表与b
中的时间间隔一样多。 c
中的每个列表都包含区间中包含x
的所有x[0]
个元素。例如:
c=[
[['10', 'name_1']],
[['50','name_2'],['40','name_3']],
[...,['80', 'name_N']]
]
答案 0 :(得分:1)
c = []
for r in b:
l = []
rn = range(*r)
for element in a:
if int(element[0]) in rn:
l.append(element)
c.append(l)
如果您的间隔非常大,请考虑使用xrange
代替range
。实际上,如果你的间隔甚至是中等大小,请考虑以下几点。
c = []
for r in b:
l = []
for element in a:
if r[0] <= int(element[0]) < r[1]:
l.append(element)
c.append(l)
答案 1 :(得分:1)
您可以在此处使用collections.defaultdict
和bisect
模块:
由于范围是连续的,所以最好先将列表b
转换成这样的内容:
[10, 40, 60, 90, 100]
这样做的好处是我们现在可以使用bisect
模块来查找列表中项目所适合的索引。例如,50将介于40和60之间,因此bisect.bisect_right
将返回在这种情况下为2。不,我们可以使用此2作为密钥并将列表存储为其值。这样我们就可以根据bisect.bisect_right
返回的索引对这些项进行分组。
L_b = 2* len(b)
L_a = len(a)
L_b1 = len(b1)
整体复杂性将是:max ( L_b log L_b , L_a log L_b1 )
>>> import bisect
>>> from collections import defaultdict
>>> b=[(10,40),(40,60),(60,90),(90,100)]
>>> b1 = sorted( set(z for x in b for z in x))
>>> b1
[10, 40, 60, 90, 100]
>>> dic = defaultdict(list)
for x,y in a:
#Now find the index where the value from the list can fit in the
#b1 list, bisect uses binary search so this is an O(log n ) step.
# use this returned index as key and append the list to that key.
ind = bisect.bisect_right(b1,int(x))
dic[ind].append([x,y])
...
>>> dic.values()
[[['10', 'name_1']], [['50', 'name_2'], ['40', 'name_3']], [['80', 'name_N']]]
由于dicts没有任何特定的顺序,因此使用排序来获取排序的输出:
>>> [dic[k] for k in sorted(dic)]
[[['10', 'name_1']], [['50', 'name_2'], ['40', 'name_3']], [['80', 'name_N']]]
答案 2 :(得分:0)
你可以这样做:
>>> a=[['10', 'name_1'],['50','name_2'],['40','name_3'], ['80', 'name_N']]
>>> b=[(10,40),(40,60),(60,90),(90,100)]
>>> c=[]
>>> for t in b:
... f=list(filter(lambda l: t[0]<=int(l[0])<t[1],a))
... if f: c.append(f)
...
>>> c
[[['10', 'name_1']], [['50', 'name_2'], ['40', 'name_3']], [['80', 'name_N']]]
答案 3 :(得分:0)
或者你可以这样做:
>>> a=[['10', 'name_1'],['50','name_2'],['40','name_3'], ['80', 'name_N']]
>>> b=[(10,40),(40,60),(60,90),(90,100)]
>>> filter(None, [filter(lambda l: t[0]<=int(l[0])<t[1], a) for t in b])
[[['10', 'name_1']], [['50', 'name_2'], ['40', 'name_3']], [['80', 'name_N']]]