Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python list.index()与字典_Python_List_Dictionary - Fatal编程技术网

Python list.index()与字典

Python list.index()与字典,python,list,dictionary,Python,List,Dictionary,我有一个大约50个字符串的列表。我将反复(可能数万次)需要知道列表中项目的位置。是每次使用list.index()更好,还是创建一个字典将每个项映射到它的位置更好?(我的直觉是创建字典,但我不知道列表索引的基础是什么,这可能是多余的。)使用字典映射,而不是在列表中查找项目。字典映射在求值之前使用每个项的哈希。散列比较要快得多,而且可以更快地找到(在固定时间内),而不是通过列表查找并逐项计算(在线性时间内扩展) 您可以按如下方式配置查找: import timeit setup = 'from _

我有一个大约50个字符串的列表。我将反复(可能数万次)需要知道列表中项目的位置。是每次使用list.index()更好,还是创建一个字典将每个项映射到它的位置更好?(我的直觉是创建字典,但我不知道列表索引的基础是什么,这可能是多余的。)

使用字典映射,而不是在列表中查找项目。字典映射在求值之前使用每个项的哈希。散列比较要快得多,而且可以更快地找到(在固定时间内),而不是通过列表查找并逐项计算(在线性时间内扩展)

您可以按如下方式配置查找:

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]

返回:

[47.33547496795654, 47.995683908462524, 46.79590392112732]
dict查找字符串要快得多,因为它使用哈希表,而索引的列表查找要慢得多,因为它必须根据要查找的字符串计算其中的每个字符串。

list.index()
将遍历列表,直到找到它要查找的项,这是一个线性时间操作。相比之下,在字典中查找字符串是一个常数时间操作,因此字典方法可能具有更好的性能


由于您的键是字符串,并且它们的数量相对较少,因此您可能希望探索的另一个数据结构是。

字典将更快,而且创建起来也非常快:

indexer = dict((v, i) for i, v in enumerate(thelist))
enumerate
为范围内的
i(len(thelist))
生成
(i,thelist[i])
,其中生成器表达式“交换”元组(因为您需要将内容映射到索引,而不是相反)

请注意,只有当每个列表项都是可散列的时,这才有效,但是既然您说这些项是字符串,那么您就可以了


dict
,除其他外,可以快速地将一个
(键、值)
元组的iterable转换成相应的字典。

奇怪的是,现在看到
dict
这样使用-大多数人都会选择dict comp:)索引列表的好方法。(我不接受这个答案,因为它不适用于我的上下文,在我的上下文中,随着时间的推移,列表和字典将同时建立,一次一个条目,尽管问题中没有说明。)如果“建立”过程中的突变是通过附加或扩展实现的,那么更新字典也很容易。如果“构建”可以改变现有列表项的索引(例如,通过在随机位置插入),那么维护
dict
可能会比它的价值更麻烦——这取决于突变和访问的模式!请编辑你的Q,以全面准确地反映你的实际规格,否则我们根本无法帮助你。事实上,我得到了我想要的答案,这将更快地查找。在我的例子中,构建很容易,我不需要任何建议,这就是为什么这不是问题的一部分。嗯,我认为使用少量(不是特别短)字符串,trie可能会慢一些。我的字符串将在5-50个字符的范围内,因此,如果trie的最坏情况是字符串的长度,那就和使用list.index()一样糟糕,如果列表中最多有50个项目。@这实际上取决于您的字符串。我希望
list.index()
通常比trie慢得多,因为前者在字符串数量上是线性的,而后者在字符串长度上是线性的(请注意,每个“操作”w.r.t.
list.index()
都由比较字符串组成,而比较字符串本身在字符串长度上是线性的).但我认为散列通常比两者都快think@PurpleVermont同样,这取决于您的数据。有些情况下,trie会更快,有些情况下,哈希表会更快。无论如何,我怀疑字典不会满足你的需要——trie的想法只是一个值得思考的想法,可以帮助未来面临类似问题的访问者。当列表只有50个元素时,可能没有那么大的区别,我接受了arshajii的答案,因为这是第一个确认字典在理论上会更快的答案,因为list.index操作将是线性时间,而字典查找将是常数时间,但我非常感谢您“证明”它在实践中确实更快。@PurpleVermont first并不总是最好的,你想考虑其他人将来会遇到什么。e、 g.今天早上我刚得到一个答案:看看答案的日期。这是一个艰难的选择,因为两人都回答了这个问题——一个是理论上的,一个是实践上的。@Levermont我已经在理论上充实了我的回答。
indexer = dict((v, i) for i, v in enumerate(thelist))