我有两个相等长度的列表。第一个列表l1
包含数据。
l1 = [2, 3, 5, 7, 8, 10, ... , 23]
第二个列表l2
包含l1
中的数据所属的类别:
l2 = [1, 1, 2, 1, 3, 4, ... , 3]
如何使用列表理解或 lambda函数,根据第二个列表中1, 2, 3, 4
等数字定义的位置对第一个列表进行分区。例如,第一个列表中的2, 3, 7
属于同一个分区,因为它们在第二个列表中具有相应的值。
分区数在开始时就已知。
答案 0 :(得分:9)
您可以使用字典:
>>> l1 = [2, 3, 5, 7, 8, 10, 23]
>>> l2 = [1, 1, 2, 1, 3, 4, 3]
>>> d = {}
>>> for i, j in zip(l1, l2):
... d.setdefault(j, []).append(i)
...
>>>
>>> d
{1: [2, 3, 7], 2: [5], 3: [8, 23], 4: [10]}
答案 1 :(得分:8)
如果dict
没问题,我建议使用defaultdict
:
>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> for number, category in zip(l1, l2):
... d[category].append(number)
...
>>> d
defaultdict(<type 'list'>, {1: [2, 3, 7], 2: [5], 3: [8, 23], 4: [10]})
如果您使用的是Python 2,请考虑使用itertools.izip
来提高内存效率。
这与Kasramvd的解决方案基本相同,但我认为defaultdict
使其更容易阅读。
答案 2 :(得分:2)
这将使用列表解析提供分区列表:
>>> l1 = [2, 3, 5, 7, 8, 10, 23]
>>> l2 = [1, 1, 2, 1, 3, 4, 3]
>>> [[value for i, value in enumerate(l1) if j == l2[i]] for j in set(l2)]
[[2, 3, 7], [5], [8, 23], [10]]
答案 3 :(得分:1)
嵌套列表理解:
[ [ l1[j] for j in range(len(l1)) if l2[j] == i ] for i in range(1, max(l2)+1 )]
答案 4 :(得分:1)
如果将数据存储在numpy
ndarrays 中是合理的,则可以使用扩展索引
{i:l1[l2==i] for i in set(l2)}
构建由类别代码索引的 ndarrays 字典。
与l2==i
相关联的开销(即,为每个类别构建新的布尔数组)随着类别数量的增长而增长,因此您可能想要检查哪个替代方案numpy
或defaultdict
,您的数据更快。
我使用n=200000
进行了测试,nc=20
和numpy
的速度高于defaultdict
+ izip
(124 vs 165 ms),但使用nc=10000
numpy
(更慢)(11300 vs 251 ms)
答案 5 :(得分:1)
使用一些itertools
和operator
好东西,你可以在一个班轮内完成这项工作:
>>> l1 = [2, 3, 5, 7, 8, 10, 23]
>>> l2 = [1, 1, 2, 1, 3, 4, 3]
>>> itertools.groupby(sorted(zip(l2, l1)), operator.itemgetter(0))
结果是itertools.groupby
对象可以迭代:
>>> for g, li in itertools.groupby(sorted(zip(l2, l1)), operator.itemgetter(0)):
>>> print(g, list(map(operator.itemgetter(1), li)))
1 [2, 3, 7]
2 [5]
3 [8, 23]
4 [10]
答案 6 :(得分:1)
这不是列表理解,而是字典理解。它类似于@ cromod的解决方案,但保留了l2
的“类别”:
{k:[val for i, val in enumerate(l1) if k == l2[i]] for k in set(l2)}
输出:
>>> l1
[2, 3, 5, 7, 8, 10, 23]
>>> l2
[1, 1, 2, 1, 3, 4, 3]
>>> {k:[val for i, val in enumerate(l1) if k == l2[i]] for k in set(l2)}
{1: [2, 3, 7], 2: [5], 3: [8, 23], 4: [10]}
>>>