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:返回列表中第一个元素的索引,使传递的函数为真_Python_List_Function_Indexing - Fatal编程技术网

Python:返回列表中第一个元素的索引,使传递的函数为真

Python:返回列表中第一个元素的索引,使传递的函数为真,python,list,function,indexing,Python,List,Function,Indexing,list.index(x)函数返回值为x的第一项列表中的索引 是否有一个类似于具有函数f()作为参数的index()函数的函数list\u func\u index()。函数f()在列表的每个元素e上运行,直到f(e)返回True。然后list\u func\u index()返回e的索引 代码方面: >>> def list_func_index(lst, func): for i in range(len(lst)): if func(lst[i

list.index(x)
函数返回值为
x
的第一项列表中的索引

是否有一个类似于具有函数
f()
作为参数的
index()
函数的函数
list\u func\u index()
。函数
f()
在列表的每个元素
e
上运行,直到
f(e)
返回
True
。然后
list\u func\u index()
返回
e
的索引

代码方面:

>>> def list_func_index(lst, func):
      for i in range(len(lst)):
        if func(lst[i]):
          return i
      raise ValueError('no element making func True')

>>> l = [8,10,4,5,7]
>>> def is_odd(x): return x % 2 != 0
>>> list_func_index(l,is_odd)
3

有更优雅的解决方案吗?(还有一个更好的函数名称)

一种可能是内置函数:

def index_of_first(lst, pred):
    for i,v in enumerate(lst):
        if pred(v):
            return i
    return None
典型的做法是将您描述的函数称为“谓词”;对于某些问题,它返回true或false。这就是为什么我在我的示例中称它为
pred


我还认为返回
None
更好,因为这才是问题的真正答案。如果需要,调用者可以选择在
None
上进行分解。

您可以通过列表理解来执行此操作:

l = [8,10,4,5,7]
filterl = [a for a in l if a % 2 != 0]

然后filterl将返回满足表达式a%2!=0我想说一个更优雅的方法…

不是一个单一的功能,但您可以很容易地完成:

>>> test = lambda c: c == 'x'
>>> data = ['a', 'b', 'c', 'x', 'y', 'z', 'x']
>>> map(test, data).index(True)
3
>>>
如果您不想一次评估整个列表,可以使用itertools,但它没有那么漂亮:

>>> from itertools import imap, ifilter
>>> from operator import itemgetter
>>> test = lambda c: c == 'x'
>>> data = ['a', 'b', 'c', 'x', 'y', 'z']
>>> ifilter(itemgetter(1), enumerate(imap(test, data))).next()[0]
3
>>> 
不过,仅仅使用生成器表达式可能比itertools更具可读性

注意:在Python3中,
map
filter
返回惰性迭代器,您只需使用:

from operator import itemgetter
test = lambda c: c == 'x'
data = ['a', 'b', 'c', 'x', 'y', 'z']
next(filter(itemgetter(1), enumerate(map(test, data))))[0]  # 3

您可以使用发电机在一个班轮中执行此操作:

next(i for i,v in enumerate(l) if is_odd(v))
生成器的好处在于,它们只计算所需的数量。因此,请求前两个索引(几乎)同样容易:

y = (i for i,v in enumerate(l) if is_odd(v))
x1 = next(y)
x2 = next(y)

不过,在最后一个索引之后(生成器就是这样工作的)会出现StopIteration异常。在“先采取”的方法中,知道没有找到这样的值也很方便——list.index()函数会在这里抛出ValueError。

@Paul接受的答案是最好的,但这里有一个小小的横向思维变体,主要是为了娱乐和指导目的……:

>>> class X(object):
...   def __init__(self, pred): self.pred = pred
...   def __eq__(self, other): return self.pred(other)
... 
>>> l = [8,10,4,5,7]
>>> def is_odd(x): return x % 2 != 0
... 
>>> l.index(X(is_odd))
3
本质上,
X
的目的是将“相等”的含义从正常意义更改为“满足此谓词”,从而允许在定义为检查相等的各种情况下使用谓词——例如,它还允许您编码,而不是
(如果有的话)(在l中X是奇数):
,如果X(是奇数)在l:中,则较短的
,以此类推


值得使用吗?当@Paul所采取的更明确的方法同样方便时(特别是当改变为使用新的、闪亮的内置
next
函数而不是旧的、不太合适的
.next
方法时,正如我在对该答案的评论中所建议的那样),情况并非如此,但在其他情况下它(或该想法的其他变体“调整平等的含义”,也许还有其他的比较器和/或散列法)可能是合适的。大多数情况下,值得了解这个想法,以避免有一天不得不从头开始发明它;-)。

是Alex答案的变体。这避免了每次你想使用
是奇数的
或任何谓词时都必须键入
X

>>> class X(object):
...     def __init__(self, pred): self.pred = pred
...     def __eq__(self, other): return self.pred(other)
... 
>>> L = [8,10,4,5,7]
>>> is_odd = X(lambda x: x%2 != 0)
>>> L.index(is_odd)
3
>>> less_than_six = X(lambda x: x<6)
>>> L.index(less_than_six)
2
>>X类(对象):
…def\uuuu init\uuuu(self,pred):self.pred=pred
…定义(self,other):返回self.pred(other)
... 
>>>L=[8,10,4,5,7]
>>>奇数=X(λX:X%2!=0)
>>>L.指数(奇数)
3.
>>>小于六=X(λX:X>>L.index(小于六)
2.

更优雅、名称更好的索引我认为OP想要模拟索引的行为,如果找不到给定的值,则会引发ValueError。+1表示enumerate,这是我的最爱。我不记得上一次在python中使用老式的C方式维护索引变量是什么时候了。不幸的是,这会计算整个list-最好有一个短路的解决方案,即在找到第一个匹配项时立即返回。您是否可以编辑您的答案,使其更像OP的函数,该函数有一个列表和函数作为参数?这是错误的。它返回一个值列表,而不是单个索引。filterl=[a对于l中的a,如果是奇数(a)]我说过,你可以通过列表理解来实现这一点,而且它会返回一个列表。我只是想给出一个不同的选项,因为我不确定bandana的确切问题是什么。很好!但是我们会“命名”X吗?可能是“键”之类的东西?因为它让我想起l.sort(Key=fn)。你几乎可以称它为“等于”“,所以这行是l.index(Equals(is_odd)),我认为Alex(隐式)建议的,
满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足满足ref=[8,10,4,5,7]def is_odd(x):返回x%2!=0类满足(object):def u init_uuuuuuuuuuuuuuuuuuuuuuuuuuuuo(self,test_uthis):self.pred(test_uthis)print ref.index(满足(is_uodd))>>3这不是模糊的-或者至少,它不会比使用
map(f,seq)更模糊
而不是
[f(x)表示序列中的x]
是。换句话说,它是惯用的。和其他惯用语一样,在它成为你词汇表的一部分之前,它并不简单。只是提醒你,如果可能不满足结束条件,就抓住
停止迭代
。小提示:
下一步
接受第二个参数,如果不匹配,它将返回,而不是提出
停止迭代操作