Python优化如何在列表中查找重复值和值索引

标签 python performance list optimization duplicates

我有一个包含 18000 个唯一 ID 的列表。 ID 是字母 A、B、C、D 的串联。 我制作了一个代码,按 ID[0:-1] 对 ID 进行分组,并给出重复 ID 的索引位置。

效果很好,但进行起来很长:对于 18 000 ID,大约 110 秒。 您有加快我的代码速度的想法吗?

a = ['1CDABCABDA', '1CDABCABDB', '1CDABCABDD', '1BCABCCCAA', '1DDAABBBBA', '1BCABCCCAD']

startTime = time.time()
b = [i[0:-1] for i in a]
b = list(set(b))


result = range(len(b))
it = 0
for i in result:
    result[i] = [b[i], []]
    for j in xrange(len(a)):
        if b[i] == a[j][0:-1]:
            result[i][1].append(j)

endTime =  time.time()

print endTime - startTime, 'secs !'

输出:

>>> [['1CDABCABD', [0, 1, 2]], ['1DDAABBBB', [4]], ['1BCABCCCA', [3, 5]]]

最佳答案

作为解决此类问题的更 Pythonic 方式,请使用 collections.defaultdict :

>>> from collections import defaultdict
>>> d=defaultdict(list)
>>> new=[i[:-1] for i in a]

>>> d=defaultdict(list)
>>> for i,j in enumerate(new):
...    d[j].append(i)
... 
>>> d
defaultdict(<type 'list'>, {'1CDABCABD': [0, 1, 2], '1DDAABBBB': [4], '1BCABCCCA': [3, 5]})
>>> d.items()
[('1CDABCABD', [0, 1, 2]), ('1DDAABBBB', [4]), ('1BCABCCCA', [3, 5])]

请注意 defaultdict 是线性解决方案,比itertools.groupbysorted 更有效。

你也可以只使用 dict.setdefault 方法:

>>> d={}
>>> for i,j in enumerate(new):
...   d.setdefault(j,[]).append(i)
... 
>>> d
{'1CDABCABD': [0, 1, 2], '1DDAABBBB': [4], '1BCABCCCA': [3, 5]}

有关更多详细信息,请查看以下基准测试,它的 ~4X 速度更快:

s1="""
from itertools import groupby
a = ['1CDABCABDA', '1CDABCABDB', '1CDABCABDD', '1BCABCCCAA', '1DDAABBBBA', '1BCABCCCAD']
key = lambda i: a[i][:-1]
indexes = sorted(range(len(a)), key=key)
result = [[x, list(y)] for x, y in groupby(indexes, key=key)]
"""
s2="""
a = ['1CDABCABDA', '1CDABCABDB', '1CDABCABDD', '1BCABCCCAA', '1DDAABBBBA', '1BCABCCCAD']
new=[i[:-1] for i in a]
d={}
for i,j in enumerate(new):
   d.setdefault(j,[]).append(i)
d.items()
    """


print ' first: ' ,timeit(stmt=s1, number=100000)
print 'second : ',timeit(stmt=s2, number=100000)

结果:

 first:  0.949549913406
second :  0.250894069672

关于Python优化如何在列表中查找重复值和值索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29733813/

相关文章:

Python - 对象的参数及其作为函数参数的值

python - cv2.circle() 未显示

python - 在使用 Raspberry Pi 寻找圆圈时,如何提高 FPS 并减少延迟?

list - 轻松复制 Prolog :) 中的元素

arrays - Openscad 位于数组或等效数组中

python - 合并(连接)带有缺失值和不同类型(str & int)的 Pandas 列

python - 如何识别数据框中具有连续索引的子集

Java 应用程序性能问题

java - 是什么让我的代码使用这么多内存?

MySql:使用复合 PK 的长列表对多行进行操作