如何查找列表中所有出现的元素?

Bru*_*uce 326 python list

index()只会在列表中首次出现一个项目.是否有一个巧妙的技巧可以返回列表中的所有索引?

Sve*_*ach 473

您可以使用列表理解:

indices = [i for i, x in enumerate(my_list) if x == "whatever"]
Run Code Online (Sandbox Code Playgroud)

  • 列表推导出现在python 2.0中,`enumerate`出现在2.3.所以是的,如果你的Python很古老,请使用`filter()`. (37认同)
  • @AndersonGreen:术语"多维数组"表示数据结构保证沿其每个轴具有统一的大小.纯Python中没有这样的数据结构.有列表列表,但它们与"多维数组"非常不同.如果你想要后者,你应该考虑使用NumPy,它允许你为一个NumPy数组`a`做``(a == 1).nonzero()`. (8认同)
  • 在较旧的pythons上,使用filter()实现基本相同的功能. (2认同)
  • 此技术不会在多维数组中找到所有项目.例如,`print([i for i,x in enumerate([[1,1],[0,1]])if x == 1])`返回`[]`而不是`[[0,1} ],[0,0],[1,1]]`. (2认同)
  • @MadmanLee如果你想要快速的东西,请使用NumPy.查看[JoshAdel]的答案(/sf/answers/440632111/) (2认同)

Jos*_*del 104

虽然不是直接列表的解决方案,但numpy真的很明显这样的事情:

import numpy as np
values = np.array([1,2,3,1,2,4,5,6,3,2,1])
searchval = 3
ii = np.where(values == searchval)[0]
Run Code Online (Sandbox Code Playgroud)

收益:

ii ==>array([2, 8])
Run Code Online (Sandbox Code Playgroud)

对于具有大量元素的列表(数组)与其他一些解决方案相比,这可以明显更快.

  • @Hari我从 `np.where([7, 8, 9, 8] == 8)[0]` 和 `np.where(np.array([7, 8, 9, 8]) = 得到不同的结果= 8)[0]`; 只有后者才能按预期工作。 (6认同)
  • @amelia` [0]`是必需的'因为`where`返回一个元组`(array([2,8],dtype = int64),)` (5认同)
  • 我注意到最后[0]将数组转换为字符串.我很好奇你为什么选择这样做. (2认同)
  • @Tomer首先`all_id_resp_address`应该是`np.array`而不是`list`. (2认同)

Pau*_*ida 28

解决方案使用list.index:

def indices(lst, element):
    result = []
    offset = -1
    while True:
        try:
            offset = lst.index(element, offset+1)
        except ValueError:
            return result
        result.append(offset)
Run Code Online (Sandbox Code Playgroud)

enumerate对于大型列表,它比列表理解要快得多.如果您已经拥有阵列,它也比numpy解决方案慢得多,否则转换成本超过速度增益(在100,1000和10000元素的整数列表上测试).

注意:基于Chris_Rands评论的注意事项:如果结果足够稀疏,此解决方案比列表解析更快,但如果列表中有许多正在搜索的元素实例(超过列表的约15%) ,在具有1000个整数列表的测试中,列表理解更快.

  • 你说这比列表压缩更快,你能展示你的时间来证明这一点吗? (4认同)
  • 这是很久以前的事了,我可能用`timeit.timeit`和随机生成的列表.这是一个重要的观点,我想这可能就是你问的原因.当时我没有想到,但速度增加只有在结果足够稀疏时才会出现.我刚刚测试了一个完整的要搜索的元素列表,它比列表理解慢得多. (3认同)

NPE*_*NPE 17

怎么样:

In [1]: l=[1,2,3,4,3,2,5,6,7]

In [2]: [i for i,val in enumerate(l) if val==3]
Out[2]: [2, 4]
Run Code Online (Sandbox Code Playgroud)


Tre*_*ney 11

    \n
  • 此答案while-loop中的内容是经过测试的最快实现。\n
      \n
    • 它比下面接受的答案快26 %test2()
    • \n
    \n
  • \n
  • \xe2\x80\x99s 是一个用于查找单个值的索引的答案np.where,如果包含将列表转换为数组的时间,则该答案并不比列表理解更快
  • \n
  • 在大多数情况下,导入numpya 并将其转换list为 a的开销numpy.array可能会导致使用numpy效率较低的选项。有必要进行仔细的时序分析。\n
      \n
    • 如果需要在 上执行多个函数/操作list,则将 转换listarray,然后使用numpy函数可能是更快的选择。
    • \n
    \n
  • \n
  • 此解决方案使用np.where和来查找列表中所有唯一元素np.unique的索引。\n
      \n
    • 在数组上使用np.where(包括将列表转换为数组的时间)比列表上的列表理解稍慢,用于查找所有唯一元素的所有索引
    • \n
    • 这已经在具有 4 个唯一值的 2M 元素列表上进行了测试,列表/数组的大小和唯一元素的数量都会产生影响。
    • \n
    \n
  • \n
  • numpy在数组上使用的其他解决方案可以在获取 numpy 数组中重复元素的所有索引的列表中找到
  • \n
  • 测试于[python 3.10.4, numpy 1.23.1][python 3.11.0, numpy 1.23.4]
  • \n
\n
import numpy as np\nimport random  # to create test list\n\n# create sample list\nrandom.seed(365)\nl = [random.choice([\'s1\', \'s2\', \'s3\', \'s4\']) for _ in range(20)]\n\n# convert the list to an array for use with these numpy methods\na = np.array(l)\n\n# create a dict of each unique entry and the associated indices\nidx = {v: np.where(a == v)[0].tolist() for v in np.unique(a)}\n\n# print(idx)\n{\'s1\': [7, 9, 10, 11, 17],\n \'s2\': [1, 3, 6, 8, 14, 18, 19],\n \'s3\': [0, 2, 13, 16],\n \'s4\': [4, 5, 12, 15]}\n
Run Code Online (Sandbox Code Playgroud)\n

%timeitstr在具有 4 个唯一元素的 2M 元素列表上

\n
# create 2M element list\nrandom.seed(365)\nl = [random.choice([\'s1\', \'s2\', \'s3\', \'s4\']) for _ in range(2000000)]\n
Run Code Online (Sandbox Code Playgroud)\n

功能

\n
def test1():\n    # np.where: convert list to array and find indices of a single element\n    a = np.array(l)\n    return np.where(a == \'s1\')\n    \n\ndef test2():\n    # list-comprehension: on list l and find indices of a single element\n    return [i for i, x in enumerate(l) if x == "s1"]\n\n\ndef test3():\n    # filter: on list l and find indices of a single element\n    return list(filter(lambda i: l[i]=="s1", range(len(l))))\n\n\ndef test4():\n    # use np.where and np.unique to find indices of all unique elements: convert list to array\n    a = np.array(l)\n    return {v: np.where(a == v)[0].tolist() for v in np.unique(a)}\n\n\ndef test5():\n    # list comprehension inside dict comprehension: on list l and find indices of all unique elements\n    return {req_word: [idx for idx, word in enumerate(l) if word == req_word] for req_word in set(l)}\n\ndef get_indices1(x: list, value: int) -> list:\n    indices = list()\n    for i in range(len(x)):\n        if x[i] == value:\n            indices.append(i)\n    return indices\n\ndef get_indices2(x: list, value: int) -> list:\n    indices = list()\n    i = 0\n    while True:\n        try:\n            # find an occurrence of value and update i to that index\n            i = x.index(value, i)\n            # add i to the list\n            indices.append(i)\n            # advance i by 1\n            i += 1\n        except ValueError as e:\n            break\n    return indices\n
Run Code Online (Sandbox Code Playgroud)\n

函数调用

\n
%timeit test1()  # list of indices for specified value\n%timeit test2()  # list of indices for specified value\n%timeit test3()  # list of indices for specified value\n%timeit test4()  # dict of indices of all values\n%timeit test5()  # dict of indices of all values\n%timeit get_indices1(l, \'s1\')  # list of indices for specified value\n%timeit get_indices2(l, \'s1\')  # list of indices for specified value\n
Run Code Online (Sandbox Code Playgroud)\n

结果python 3.12.0

\n
209 ms \xc2\xb1 2.93 ms per loop (mean \xc2\xb1 std. dev. of 7 runs, 1 loop each)\n78.5 ms \xc2\xb1 733 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 10 loops each)\n125 ms \xc2\xb1 757 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 10 loops each)\n340 ms \xc2\xb1 8.16 ms per loop (mean \xc2\xb1 std. dev. of 7 runs, 1 loop each)\n319 ms \xc2\xb1 2.97 ms per loop (mean \xc2\xb1 std. dev. of 7 runs, 1 loop each)\n74.9 ms \xc2\xb1 1.99 ms per loop (mean \xc2\xb1 std. dev. of 7 runs, 10 loops each)\n58.2 ms \xc2\xb1 1.03 ms per loop (mean \xc2\xb1 std. dev. of 7 runs, 10 loops each)\n
Run Code Online (Sandbox Code Playgroud)\n


phi*_*hag 10

occurrences = lambda s, lst: (i for i,e in enumerate(lst) if e == s)
list(occurrences(1, [1,2,3,1])) # = [0, 3]
Run Code Online (Sandbox Code Playgroud)


U10*_*ard 6

或使用range(python 3):

l=[i for i in range(len(lst)) if lst[i]=='something...']
Run Code Online (Sandbox Code Playgroud)

对于(蟒蛇 2):

l=[i for i in xrange(len(lst)) if lst[i]=='something...']
Run Code Online (Sandbox Code Playgroud)

然后(两种情况):

print(l)
Run Code Online (Sandbox Code Playgroud)

正如预期的那样。


pyl*_*ang 5

more_itertools.locate 查找满足条件的所有项目的索引。

from more_itertools import locate


list(locate([0, 1, 1, 0, 1, 0, 0]))
# [1, 2, 4]

list(locate(['a', 'b', 'c', 'b'], lambda x: x == 'b'))
# [1, 3]
Run Code Online (Sandbox Code Playgroud)

more_itertools是第三方库> pip install more_itertools


Gio*_* PY 5

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

使用 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]
>>>
Run Code Online (Sandbox Code Playgroud)

让我们的函数 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"))
Run Code Online (Sandbox Code Playgroud)

输出


[1, 3, 5, 7]
Run Code Online (Sandbox Code Playgroud)

简单的

for n, i in enumerate([1, 2, 3, 4, 1]):
    if i == 1:
        print(n)
Run Code Online (Sandbox Code Playgroud)

输出:

0
4
Run Code Online (Sandbox Code Playgroud)