python 列表第一个元素的索引_Python:返回列表的第一个元素的索引,该列表使传递的函数tru...

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

list_func_index()函数返回值为x的第一项列表中的索引。

是否有一个函数list_func_index(),类似于具有参数f()的index()函数。 在列表的每个元素e上运行函数f(),直到f(e)返回True。然后list_func_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

有没有更优雅的解决方案? (以及该函数的更好的名称)

6个解决方案

86 votes

您可以使用生成器在单行代码中做到这一点:

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 answered 2020-02-14T13:17:02Z

12 votes

@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

本质上,next的目的是将“平等”的含义从正常谓词更改为“满足此谓词”,从而允许在定义为检查相等性的所有情况下使用谓词-例如,它还将 让您编码,而不是.next,较短的if X(is_odd) in l:,依此类推。

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

Alex Martelli answered 2020-02-14T13:17:32Z

11 votes

一种可能是内置的枚举功能:

def index_of_first(lst, pred):

for i,v in enumerate(lst):

if pred(v):

return i

return None

通常将类似您所描述的函数称为谓词的函数。 对于某些问题,它返回true或false。 这就是为什么在我的示例中将其称为None。

我也认为最好返回None,因为这是问题的真正答案。 如果需要,呼叫者可以选择在None上爆炸。

Jonathan Feinberg answered 2020-02-14T13:18:02Z

4 votes

不是一个功能,但是您可以轻松完成:

>>> 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

>>>

但是,仅使用生成器表达式可能比map更易读。

请注意,在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

Steve Losh answered 2020-02-14T13:18:35Z

2 votes

您可以通过列表理解来做到这一点:

l = [8,10,4,5,7]

filterl = [a for a in l if a % 2 != 0]

然后filterl将返回满足表达式%2!= 0的列表的所有成员。我想说一个更优雅的方法...

Vincent Osinga answered 2020-02-14T13:18:59Z

2 votes

亚历克斯答案的变化。 这样可以避免每次要使用is_odd或任何谓词时都不必键入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

John La Rooy answered 2020-02-14T13:19:19Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值