我有一个名单l = [10,10,20,15,10,20]
。我想为每个唯一值分配一个" index"得到[1,1,2,3,1,2]
。
这是我的代码:
a = list(set(l))
res = [a.index(x) for x in l]
结果证明非常慢。
l
包含1M个元素和100K个唯一元素。我也尝试过使用lambda和排序的地图,这没有用。这样做的理想方式是什么?
答案 0 :(得分:36)
您可以使用defaultdict
和列表理解在O(N)
时间内执行此操作:
>>> from itertools import count
>>> from collections import defaultdict
>>> lst = [10, 10, 20, 15, 10, 20]
>>> d = defaultdict(count(1).next)
>>> [d[k] for k in lst]
[1, 1, 2, 3, 1, 2]
如果您想知道它是如何运作的?
传递给default_factory
的{{1}}仅在Python遇到缺失密钥时被调用,因此对于10,该值将为1,然后为在接下来的十年里,它不再是一个缺失的密钥,因此使用先前计算的1,现在20再次是一个缺失密钥,Python将再次调用count(1).next
来获取其值,依此类推。
defaultdict
将如下所示:
default_factory
答案 1 :(得分:21)
代码缓慢,因为a.index(x)
执行线性搜索,并对l
中的每个元素执行线性搜索。因此,对于您执行的每个1M项目(最多)进行100K比较。
将一个值转换为另一个值的最快方法是在地图中查找。您需要创建地图并填写原始值与所需值之间的关系。然后在列表中遇到另一个相同值时从地图中检索值。
这是一个通过l
进行单次传递的示例。可能存在进一步优化的空间,以消除在追加时重复分配res
的需要。
res = []
conversion = {}
i = 0
for x in l:
if x not in conversion:
value = conversion[x] = i
i += 1
else:
value = conversion[x]
res.append(value)
答案 2 :(得分:6)
您的解决方案很慢,因为它的复杂性为O(nm)
,m
中的l
中的唯一元素数量为a.index()
O(m)
,您称之为l
对于O(n)
中的每个元素。
要使其成为index()
,请删除>>> idx, indexes = 1, {}
>>> for x in l:
... if x not in indexes:
... indexes[x] = idx
... idx += 1
...
>>> [indexes[x] for x in l]
[1, 1, 2, 3, 1, 2]
并将索引存储在字典中:
l
如果quiz.js
仅包含已知范围内的整数,您还可以将索引存储在列表中而不是字典中,以便更快地进行查找。
答案 3 :(得分:6)
嗯,我想这取决于你是否希望它以特定的顺序返回索引。如果您希望该示例返回:
[1,1,2,3,1,2]
然后你可以查看提交的其他答案。但是,如果您只关心为每个唯一编号获取唯一索引,那么我有一个快速解决方案
import numpy as np
l = [10,10,20,15,10,20]
a = np.array(l)
x,y = np.unique(a,return_inverse = True)
并且对于此示例,y的输出为:
y = [0,0,2,1,0,2]
我测试了1,000,000个条目并且它基本上立即完成。
答案 4 :(得分:2)
您可以使用collections.OrderedDict()
按顺序保留唯一项目,并循环遍历此有序唯一项目的枚举,以获取项目和这些索引的字典(基于其顺序)然后通过这个字典包含operator.itemgetter()
的主列表,以获取每个项目的相应索引:
>>> from collections import OrderedDict
>>> from operator import itemgetter
>>> itemgetter(*lst)({j:i for i,j in enumerate(OrderedDict.fromkeys(lst),1)})
(1, 1, 2, 3, 1, 2)
答案 5 :(得分:1)
对于完整性,你也可以急切地这样做:
from itertools import count wordid = dict(zip(set(list_), count(1)))
这使用一个集合来获取
list_
对中的唯一单词 每个具有count()
下一个值的唯一单词(其中 向上计数),并根据结果构建字典。
Original answer,由nneonneo撰写。