Python:在列表中查找

Ste*_*and 513 python find

我遇到过这个:

item = someSortOfSelection()
if item in myList:
    doMySpecialFunction(item)
Run Code Online (Sandbox Code Playgroud)

但有时它不适用于我的所有项目,就好像它们在列表中未被识别一样(当它是一个字符串列表时).

这是在列表中找到一个项目的最"Python化"的方式:if x in l:

Nik*_* B. 1056

至于你的第一个问题:该代码完全正常,如果item等于其中一个元素应该可以工作myList.也许你试图找到一个与其中一个项不完全匹配的字符串,或者你正在使用一个浮点值,它会受到不准确的影响.

至于你的第二个问题:如果在列表中"找到"东西,实际上有几种可能的方法.

检查里面是否有东西

这是您描述的用例:检查列表中是否有内容.如您所知,您可以使用in运算符:

3 in [1, 2, 3] # => True
Run Code Online (Sandbox Code Playgroud)

过滤集合

也就是说,查找序列中满足特定条件的所有元素.您可以使用列表推导或生成器表达式:

matches = [x for x in lst if fulfills_some_condition(x)]
matches = (x for x in lst if x > 6)
Run Code Online (Sandbox Code Playgroud)

后者将返回一个生成器,您可以将其想象为一种惰性列表,只有在您遍历它时才会构建它.顺便说一句,第一个完全等同于

matches = filter(fulfills_some_condition, lst)
Run Code Online (Sandbox Code Playgroud)

在Python 2中,您可以在这里看到高阶函数.在Python 3中,filter不返回列表,而是返回类似于生成器的对象.

找到第一次出现

如果你只想要第一个匹配条件的东西(但你还不知道它是什么),那么使用for循环(可能也使用该else子句,这并不是很有名)是没问题的.你也可以使用

next(x for x in lst if ...)
Run Code Online (Sandbox Code Playgroud)

StopIteration如果没有找到,将返回第一场比赛或加注.或者,您可以使用

next((x for x in lst if ...), [default value])
Run Code Online (Sandbox Code Playgroud)

查找项目的位置

对于列表,index如果您想知道列表中某个元素的位置,那么这个方法有时也很有用:

[1,2,3].index(2) # => 1
[1,2,3].index(4) # => ValueError
Run Code Online (Sandbox Code Playgroud)

但请注意,如果您有重复项,请.index始终返回最低索引:......

[1,2,3,2].index(2) # => 1
Run Code Online (Sandbox Code Playgroud)

如果有重复项并且您想要所有索引,那么您可以使用enumerate():

[i for i,x in enumerate([1,2,3,2]) if x==2] # => [1, 3]
Run Code Online (Sandbox Code Playgroud)

  • 你的"找到第一次出现"的例子是金色的.感觉比`[list comprehension ...] [0]`方法更加pythonic (22认同)
  • Stephane:让我重新说一下:"如果列表中的x是*不是*人们抱怨不是内置函数的东西.他们抱怨这样一个事实,即没有明确的方法来查找匹配特定条件的列表中第一次出现的内容.但正如我的回答所述,`next()`可以(ab)用于此. (10认同)
  • 我越来越不满意python的"功能"功能.在haskell中,在Data.List模块中找到了正确执行该功能的函数.但是在python中它不是,并且它很小,使它成为一个库,所以你必须一遍又一遍地重新实现相同的逻辑.多么浪费...... (4认同)
  • @Stephane:第二个不生成元组,而是生成器(基本上是一个尚未构建的列表).如果您只想使用一次结果,通常可以选择生成器.但是,如果您想在之后多次使用创建的集合,则建议首先创建一个显式列表.看看我的更新,它现在有点更好结构:) (3认同)
  • 如果有一个kwarg到`index()`叫做`key`就像`max()`接受的`key`那样会很好; 例如:`index(list,key = is_prime)`. (2认同)

Jan*_*zny 171

如果要查找一个元素或None使用默认值next,StopIteration如果在列表中找不到该项,则不会引发:

first_or_default = next((x for x in lst if ...), None)
Run Code Online (Sandbox Code Playgroud)

  • @Devy:没错,但是`(x表示x中的x,如果......)`是列表`lst`上的生成器(*是*迭代器).如果你做`next(iter([x for x in lst if ...]),None)`,你必须构造列表`[x for x in lst if ...]`,这将是一个很大的更昂贵的操作. (7认同)
  • `next` 将迭代器作为第一个参数,列表/元组不是迭代器。所以它应该是`first_or_default = next(iter([x for x in lst if ...]), None)`见https://docs.python.org/3/library/functions.html#next (2认同)
  • 这里有一个抽象来定义一个查找函数。只需将 `if` 的布尔表达式封装在 lambda 中,您通常可以编写 `find(fn,list)`,而不是混淆生成器代码。 (2认同)

Vin*_*tin 18

虽然Niklas B.的答案非常全面,但当我们想要在列表中找到一个项目时,获取其索引有时很有用:

next((i for i, x in enumerate(lst) if [condition on x]), [default value])
Run Code Online (Sandbox Code Playgroud)


Ant*_*ins 10

找到第一次出现

有一个配方itertools:

def first_true(iterable, default=False, pred=None):
    """Returns the first true value in the iterable.

    If no true value is found, returns *default*

    If *pred* is not None, returns the first item
    for which pred(item) is true.

    """
    # first_true([a,b,c], x) --> a or b or c or x
    # first_true([a,b], x, f) --> a if f(a) else b if f(b) else x
    return next(filter(pred, iterable), default)
Run Code Online (Sandbox Code Playgroud)

例如,以下代码查找列表中的第一个奇数:

>>> first_true([2,3,4,5], None, lambda x: x%2==1)
3  
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,我猜你的意思是“more-itertools.first_true()”。很高兴知道这一点,但仍然没有一种优雅的方法可以通过语言或标准库来实现这一点,这仍然是非常荒谬的。需要默认值的“下一个”黑客很麻烦。 (3认同)
  • 如果这就是他们使用的理由,那根本没有任何意义。Ruby 并没有因为在其标准库中包含最常用的方法而变成 Lisp 或 Haskell,而且无论如何,恕我直言,函数式语言可以完全可读,而且通常比命令式语言更好。但无论如何我不应该在这里引发语言战争;-) (2认同)

Eng*_*ero 8

另一种选择:您可以使用 来检查项目是否在列表中if item in list:,但这是 O(n) 的顺序。如果您正在处理大型项目列表,并且您只需要知道某些内容是否属于您的列表,您可以先将列表转换为集合并利用恒定时间集合查找

my_set = set(my_list)
if item in my_set:  # much faster on average than using a list
    # do something
Run Code Online (Sandbox Code Playgroud)

并非在每种情况下都是正确的解决方案,但在某些情况下,这可能会给您带来更好的性能。

请注意,创建集合set(my_list)也是 O(n),所以如果您只需要这样做一次,那么这样做不会更快。如果您需要重复检查成员资格,那么在初始集合创建后的每次查找都是 O(1)。


jos*_*sef 6

定义和用法

count()方法返回具有指定值的元素数。

句法

list.count(value)
Run Code Online (Sandbox Code Playgroud)

例子:

fruits = ['apple', 'banana', 'cherry']

x = fruits.count("cherry")
Run Code Online (Sandbox Code Playgroud)

问题示例:

item = someSortOfSelection()

if myList.count(item) >= 1 :

    doMySpecialFunction(item)
Run Code Online (Sandbox Code Playgroud)

  • 这在很长的列表中有效吗?说百万名单? (2认同)