可能重复:
Python list.index问题
要查找列表中项目的索引,请使用:
list.index(x)
Return the index in the list of the first item whose value is x.
It is an error if there is no such item.
Run Code Online (Sandbox Code Playgroud)
这对我来说似乎有点奇怪,如果找不到该项目会引发错误.我来自(Objective-C land),它返回一个NSNotFound枚举(它只是一个max int,表示找不到该项).
所以我做了一些丑陋的事情来解决这个问题:
index = 0
for item in self.items:
if item.id == desired_id:
return index
index = index + 1
return -1
Run Code Online (Sandbox Code Playgroud)
我用-1来表示找不到该项目.有什么更好的方法可以做到这一点,为什么Python没有内置这样的东西?
Jak*_*yer 24
a = [1]
try:
index_value = a.index(44)
except ValueError:
index_value = -1
Run Code Online (Sandbox Code Playgroud)
这个怎么样?
返回-1并不是一个好主意,因为它是Python中的有效索引(请参阅Python list.index在找不到索引时抛出异常).
可能最好抓住索引错误并采取相应措施.
我同意所指出的一般解决方案,但我想更多地了解在答案和评论中解释的方法,以了解哪一方法更有效以及在哪些情况下.
首先,三种基本方法:
>>> def my_index(L, obj):
... for i, el in enumerate(L):
... if el == obj:
... return i
... return -1
...
>>> def my_index2(L, obj):
... try:
... return L.index(obj)
... except ValueError:
... return -1
...
>>> def my_index3(L, obj):
... if obj in L:
... return L.index(obj)
... return -1
...
Run Code Online (Sandbox Code Playgroud)
第一个和第二个解决方案只扫描列表一次,因此您可能认为它们比第三个更快,因为它扫描列表两次.所以让我们看看:
>>> timeit.timeit('my_index(L, 24999)', 'from __main__ import my_index, L', number=1000)
1.6892211437225342
>>> timeit.timeit('my_index2(L, 24999)', 'from __main__ import my_index2, L', number=1000)
0.403195858001709
>>> timeit.timeit('my_index3(L, 24999)', 'from __main__ import my_index3, L', number=1000)
0.7741198539733887
Run Code Online (Sandbox Code Playgroud)
那么第二个是真的最快的,但你可以看到,第一个是远高于第三个比较慢,即使它会扫描列表中只有一次.如果我们增加列表的大小,事情变化不大:
>>> L = list(range(2500000))
>>> timeit.timeit('my_index(L, 2499999)', 'from __main__ import my_index, L', number=100)
17.323430061340332
>>> timeit.timeit('my_index2(L, 2499999)', 'from __main__ import my_index2, L', number=100)
4.213982820510864
>>> timeit.timeit('my_index3(L, 2499999)', 'from __main__ import my_index3, L', number=100)
8.406487941741943
Run Code Online (Sandbox Code Playgroud)
第一个仍然慢2倍.
如果我们搜索一些不在列表中的内容,那么第一个解决方案的情况会变得更糟:
>>> timeit.timeit('my_index(L, None)', 'from __main__ import my_index, L', number=100)
19.055058002471924
>>> timeit.timeit('my_index2(L, None)', 'from __main__ import my_index2, L', number=100)
5.785136938095093
>>> timeit.timeit('my_index3(L, None)', 'from __main__ import my_index3, L', number=100)
5.46164608001709
Run Code Online (Sandbox Code Playgroud)
正如你在这种情况下看到的那样,第三个解决方案甚至比第二个解决方案还要好,两者都比python代码快4倍.根据您期望搜索失败的频率,您希望选择#2或#3(即使在99%的情况下,数字#2更好).
作为一般规则,如果您想为CPython优化某些内容,那么您希望尽可能多地在"C级别"进行迭代.在您的例子迭代使用for循环正是你做的东西并不想这样做.
| 归档时间: |
|
| 查看次数: |
36022 次 |
| 最近记录: |