我有一个大约50个字符串的列表。我会反复(可能数万次)需要知道列表中项目的位置。每次使用list.index()或创建将每个项目映射到其位置的字典是否更好? (我的直觉说要创建字典,但我不知道列表索引的基础,这可能是多余的。)
答案 0 :(得分:5)
list.index()
将遍历列表,直到找到它正在查找的项目,这是一个线性时间操作。相比之下,在字典中查找字符串是一个固定时间操作,因此字典方法可能会有更好的性能。
由于您的密钥是字符串而且您的密钥相对较少,因此您可能想要探索的另一种数据结构是trie。
答案 1 :(得分:1)
使用字典映射而不是查找列表中的项目。字典映射在评估之前使用每个项的散列。哈希比较速度更快,可以更快地找到(在恒定时间内),而不是通过列表进行搜索并逐项评估(按线性时间缩放)。
您可以像这样分析您的查询:
import timeit
setup = 'from __main__ import foo_dict, foo_list'
限制列表的比较仅为50长:
l = list(str(i) for i in range(50))
d = dict((str(i), i) for i in range(50))
def foo_dict(k):
return d[k]
def foo_list(k):
return l.index(k)
timeit.repeat('[foo_dict(str(i)) for i in range(50)]', setup)
为我回报:
[20.89474606513977, 23.206938982009888, 22.23725199699402]
和
timeit.repeat('[foo_list(str(i)) for i in range(50)]', setup)
返回:
[47.33547496795654, 47.995683908462524, 46.79590392112732]
字符串的dict查找速度要快得多,因为它使用散列表,而索引的列表查找要慢得多,因为它必须根据要查找的字符串计算其中的每个字符串。
答案 2 :(得分:1)
字典会更快,创建速度也非常快:
indexer = dict((v, i) for i, v in enumerate(thelist))
enumerate
为(i, thelist[i])
产生i in range(len(thelist))
,因为生成器表达式“交换”元组(因为您需要将内容映射到索引,反之亦然)。
请注意,这仅适用于每个列表项都是可清除的,但由于您说项目是字符串,因此您应该没问题。
除其他事项外, dict
会快速将(key, value)
元组的可迭代变为相应的字典。