list索引 - python list遍历




在Python中查找包含它的列表的项目索引 (19)

在Python中查找包含它的列表的项目索引

对于列表["foo", "bar", "baz"]和列表"bar"的项目,在Python中获取其索引(1)的最简洁方法是什么?

嗯,当然,有索引方法,它返回第一次出现的索引:

>>> l = ["foo", "bar", "baz"]
>>> l.index('bar')
1

这种方法存在一些问题:

  • 如果值不在列表中,您将获得ValueError
  • 如果列表中有多个值,则只获取第一个值的索引

没有价值

如果值可能丢失,则需要捕获ValueError

您可以使用如下可重用的定义来执行此操作:

def index(a_list, value):
    try:
        return a_list.index(value)
    except ValueError:
        return None

并像这样使用它:

>>> print(index(l, 'quux'))
None
>>> print(index(l, 'bar'))
1

而这样做的缺点是你可能会检查返回的值is is not None:

result = index(a_list, value)
if result is not None:
    do_something(result)

列表中有多个值

如果你可能有更多的事件,你将无法获得list.index完整信息:

>>> l.append('bar')
>>> l
['foo', 'bar', 'baz', 'bar']
>>> l.index('bar')              # nothing at index 3?
1

您可以枚举列表中的索引:

>>> [index for index, v in enumerate(l) if v == 'bar']
[1, 3]
>>> [index for index, v in enumerate(l) if v == 'boink']
[]

如果没有出现,可以使用结果的布尔检查来检查,或者如果循环结果则不执行任何操作:

indexes = [index for index, v in enumerate(l) if v == 'boink']
for index in indexes:
    do_something(index)

更好的数据与熊猫交配

如果您有pandas,可以使用Series对象轻松获取此信息:

>>> import pandas as pd
>>> series = pd.Series(l)
>>> series
0    foo
1    bar
2    baz
3    bar
dtype: object

比较检查将返回一系列布尔值:

>>> series == 'bar'
0    False
1     True
2    False
3     True
dtype: bool

通过下标符号将该系列布尔值传递给系列,您只得到匹配的成员:

>>> series[series == 'bar']
1    bar
3    bar
dtype: object

如果只需要索引,index属性将返回一系列整数:

>>> series[series == 'bar'].index
Int64Index([1, 3], dtype='int64')

如果你想要它们在列表或元组中,只需将它们传递给构造函数:

>>> list(series[series == 'bar'].index)
[1, 3]

是的,你也可以使用枚举的列表理解,但是在我看来,这不是那么优雅 - 你在Python中进行相等的测试,而不是让用C编写的内置代码处理它:

>>> [i for i, value in enumerate(l) if value == 'bar']
[1, 3]

这是XY问题吗?

XY问题是询问您尝试的解决方案而不是实际问题。

为什么你认为你需要给定列表中的元素的索引?

如果您已经知道该值,为什么要关注它在列表中的位置?

如果值不存在,捕获ValueError相当冗长 - 我宁愿避免这种情况。

我通常会在列表上进行迭代,所以我通常会指向任何有趣的信息,并使用枚举来获取索引。

如果您正在调整数据,那么您应该使用pandas - 它拥有比我所展示的纯Python工作区更优雅的工具。

我不记得需要list.index ,我自己。 但是,我查看了Python标准库,我发现它有一些很好的用途。

idlelib有很多很多用途,用于GUI和文本解析。

keyword模块使用它来查找模块中的注释标记,以通过元编程自动重新生成其中的关键字列表。

在Lib / mailbox.py中,它似乎像有序映射一样使用它:

key_list[key_list.index(old)] = new

del key_list[key_list.index(key)]

在Lib / http / cookiejar.py中,似乎用于下个月:

mon = MONTHS_LOWER.index(mon.lower())+1

在Lib / tarfile.py中类似于distutils来获取切片到项目:

members = members[:members.index(tarinfo)]

在Lib / pickletools.py中:

numtopop = before.index(markobject)

这些用法似乎有共同之处在于它们似乎在约束大小的列表上运行(因为list.index的O(n)查找时间很重要),并且它们主要用于解析(以及用于解析的UI)闲)。

虽然有用例,但它们并不常见。 如果您发现自己正在寻找这个答案,那么问问自己,您所做的事情是否是最直接使用该语言为您的用例提供的工具。

对于列表["foo", "bar", "baz"]和列表"bar" ,如何在Python中获取其索引(1)?


如果表现令人担忧:

在许多答案中提到list.index(item)方法的内置方法是O(n)算法。 如果您需要执行一次,这很好。 但是如果你需要多次访问元素索引,首先创建一个项目索引对的字典(O(n)),然后每次需要时在O(1)处访问索引更有意义。它。

如果您确定列表中的项目永远不会重复,您可以轻松地:

myList = ["foo", "bar", "baz"]

# Create the dictionary
myDict = dict((e,i) for i,e in enumerate(myList))

# Lookup
myDict["bar"] # Returns 1
# myDict.get("blah") if you don't want an error to be raised if element not found.

如果您可能有重复的元素,并且需要返回所有索引:

from collections import defaultdict as dd
myList = ["foo", "bar", "bar", "baz", "foo"]

# Create the dictionary
myDict = dd(list)
for i,e in enumerate(myList):
    myDict[e].append(i)

# Lookup
myDict["foo"] # Returns [0, 4]

获取列表中一个或多个(相同)项的所有出现次数和位置

使用enumerate(alist),当元素x等于您查找的内容时,您可以存储第一个元素(n),它是列表的索引。

>>> alist = ['foo', 'spam', 'egg', 'foo']
>>> foo_indexes = [n for n,x in enumerate(alist) if x=='foo']
>>> foo_indexes
[0, 3]
>>>

让我们的函数findindex

此函数将项目和列表作为参数,并返回列表中项目的位置,就像我们之前看到的那样。

def indexlist(item2find, list_or_string):
  "Returns all indexes of an item in a list or a string"
  return [n for n,item in enumerate(list_or_string) if item==item2find]

print(indexlist("1", "010101010"))

产量

[1, 3, 5, 7]

简单

for n, i in enumerate([1, 2, 3, 4, 1]):
    if i == 1:
        print(n)

输出:

0
4

index()返回第一个值的索引!

| 指数(...)
| L.index(value,[start,[stop]]) - > integer - 返回第一个值的索引

def all_indices(value, qlist):
    indices = []
    idx = -1
    while True:
        try:
            idx = qlist.index(value, idx+1)
            indices.append(idx)
        except ValueError:
            break
    return indices

all_indices("foo", ["foo","bar","baz","foo"])

具有zip功能的所有索引:

get_indexes = lambda x, xs: [i for (y, i) in zip(xs, range(len(xs))) if x == y]

print get_indexes(2, [1, 2, 3, 4, 5, 6, 3, 2, 3, 2])
print get_indexes('f', 'xsfhhttytffsafweef')

另外一个选项

>>> a = ['red', 'blue', 'green', 'red']
>>> b = 'red'
>>> offset = 0;
>>> indices = list()
>>> for i in range(a.count(b)):
...     indices.append(a.index(b,offset))
...     offset = indices[-1]+1
... 
>>> indices
[0, 3]
>>> 

如果元素不在列表中,则会出现问题。 此函数处理问题:

# if element is found it returns index of element else returns None

def find_element_in_list(element, list_element):
    try:
        index_element = list_element.index(element)
        return index_element
    except ValueError:
        return None

如果列表没有您需要检查索引的重复项,则有两种可能性

 eg: li=[10,20,30] # here need to get index of 20 means
     li.index(20) # will work properly because 20 is not repeated

如果它的重复意味着它只会给你第一个索引

如果您需要获取项目所在的所有索引,则表示

eg: li=[10,20,30,20,40, 50, 10] # here need to get index of 20 means its have 2 index (1,3) 

得到你需要这样做

 li=[10,20,30,20,40, 50, 10]
 [i for i, e in enumerate(li) if e == 20]

然后你会得到一个索引列表为o / p,如[1,3]


如果找不到该项,Python index()方法会抛出错误,这很糟糕!

所以你可以使它类似于JavaScript的indexOf()函数,如果找不到该项,则返回-1

    try:
        index = array.index('search_keyword')
    except ValueError:
        index = -1

学习Python真正有用的一件事是使用交互式帮助功能:

>>> help(["foo", "bar", "baz"])
Help on list object:

class list(object)
 ...

 |
 |  index(...)
 |      L.index(value, [start, [stop]]) -> integer -- return first index of value
 |

这通常会引导您找到您正在寻找的方法。


对此有一个更实用的答案。

list(filter(lambda x: x[1]=="bar",enumerate(["foo", "bar", "baz", "bar", "baz", "bar", "a", "b", "c"])))

更通用的形式:

def get_index_of(lst, element):
    return list(map(lambda x: x[0],\
       (list(filter(lambda x: x[1]==element, enumerate(lst))))))

您必须设置条件以检查您要搜索的元素是否在列表中

if 'your_element' in mylist:
    print mylist.index('your_element')
else:
    print None

查找列表L中项目x的索引:

idx = L.index(x) if (x in L) else -1

正如@TerryA所指出的,许多答案都讨论了如何找到一个索引。

more_itertools是一个第三方库,其中包含用于在iterable中定位多个索引的工具。

特定

import more_itertools as mit


iterable = ["foo", "bar", "baz", "ham", "foo", "bar", "baz"]

查找多个观察的索引:

list(mit.locate(iterable, lambda x: x == "bar"))
# [1, 5]

测试多个项目:

list(mit.locate(iterable, lambda x: x in {"bar", "ham"}))
# [1, 3, 5]

另请参阅more_itertools.locate更多选项。 通过more_itertools


获取所有索引:

 indexes = [i for i,x in enumerate(xs) if x == 'foo']

让我们将名称命名为lst到您拥有的列表中。 可以将列表lst转换为numpy array 。 然后,使用numpy.where获取列表中所选项的索引。 以下是您实施它的方式。

 import numpy as np lst = ["foo", "bar", "baz"] #lst: : 'list' data type lst_np = np.array(lst) #lst_np: 'numpy.ndarray' index = np.where( lst_np == 'bar')[0][0] #index: 'numpy.int64' data type print index 1 

这里提出的所有函数都重现了固有的语言行为,但却模糊了正在发生的事情。

[i for i in range(len(mylist)) if mylist[i]==myterm]  # get the indices

[each for each in mylist if each==myterm]             # get the items

mylist.index(myterm) if myterm in mylist else None    # get the first index and fail quietly

如果语言提供了自己想做的方法,为什么要编写一个带异常处理的函数?


>>> ["foo", "bar", "baz"].index("bar")
1

参考: 数据结构>更多列表

警告如下

请注意,尽管这可能是回答问题的最简洁方法,但indexlist API的一个相当弱的组件,我不记得上次我在愤怒中使用它了。 在评论中已经向我指出,因为这个答案被大量引用,所以应该更加完整。 关于list.index一些警告如下。 最初可能需要查看文档字符串:

>>> print(list.index.__doc__)
L.index(value, [start, [stop]]) -> integer -- return first index of value.
Raises ValueError if the value is not present.

列表长度的线性时间复杂度

index调用按顺序检查列表中的每个元素,直到找到匹配项。 如果您的列表很长,而且您不清楚列表中的大致位置,则此搜索可能会成为瓶颈。 在这种情况下,您应该考虑不同的数据结构。 请注意,如果您大致知道匹配的位置,则可以为index提供提示。 例如,在这个片段中, l.index(999_999, 999_990, 1_000_000)比直接l.index(999_999)快大约五个数量级,因为前者只需搜索10个条目,而后者搜索一百万个:

>>> import timeit
>>> timeit.timeit('l.index(999_999)', setup='l = list(range(0, 1_000_000))', number=1000)
9.356267921015387
>>> timeit.timeit('l.index(999_999, 999_990, 1_000_000)', setup='l = list(range(0, 1_000_000))', number=1000)
0.0004404920036904514

仅将第一个匹配的索引返回到其参数

index的调用按顺序搜索列表,直到找到匹配项,然后停在那里。 如果您希望需要更多匹配的索引,则应使用列表推导或生成器表达式。

>>> [1, 1].index(1)
0
>>> [i for i, e in enumerate([1, 2, 1]) if e == 1]
[0, 2]
>>> g = (i for i, e in enumerate([1, 2, 1]) if e == 1)
>>> next(g)
0
>>> next(g)
2

我曾经使用过index大多数地方,我现在使用列表推导或生成器表达式,因为它们更具有推广性。 因此,如果您正在考虑使用index ,请查看这些出色的python功能。

如果元素不在列表中,则抛出

如果项目不存在,则对index的调用会导致ValueError

>>> [1, 1].index(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: 2 is not in list

如果该项目可能不在列表中,您应该

  1. 首先使用item in my_list检查它(干净,可读的方法),或
  2. index调用包装在try/except块中,该块捕获ValueError (可能更快,至少当搜索列表很长时,该项通常存在。)

name ="bar"
list = [["foo", 1], ["bar", 2], ["baz", 3]]
new_list=[]
for item in list:
    new_list.append(item[0])
print(new_list)
try:
    location= new_list.index(name)
except:
    location=-1
print (location)

这说明字符串是否也不在列表中,如果它不在列表中,则location = -1





list