list.index(x)
函数返回值为x
的第一个项目列表中的索引。
是否有一个函数list_func_index()
,类似于具有函数index()
的{{1}}函数作为参数。函数f()
在列表的每个元素f()
上运行,直到e
返回f(e)
。然后True
返回list_func_index()
的索引。
Codewise:
e
有更优雅的解决方案吗? (以及该功能的更好名称)
答案 0 :(得分:78)
您可以使用生成器在单行中执行此操作:
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。
答案 1 :(得分:12)
@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
的目的是将“相等”的含义从正常变为“满足此谓词”,从而允许在各种情况下使用谓词来定义为检查相等 - 例如,它还允许您编码而不是if any(is_odd(x) for x in l):
,而不是if X(is_odd) in l:
,等等。
值得使用?当@Paul采用的更明确的方法同样方便时(特别是当更改为使用新的,有光泽的内置next
函数而不是旧的,不太合适的.next
方法时)我建议在对该答案的评论中),但在其他情况下,它(或其他变体的想法“调整平等的含义”,也许其他比较器和/或散列)可能是合适的。大多数情况下,值得了解这个想法,以避免有一天从头开始发明它; - )。
答案 2 :(得分:11)
一种可能性是内置enumerate功能:
def index_of_first(lst, pred):
for i,v in enumerate(lst):
if pred(v):
return i
return None
通常会将您描述的函数称为“谓词”;某些问题会返回true或false。这就是我在我的例子中称之为pred
的原因。
我还认为返回None
会更好,因为这是问题的真正答案。如果需要,呼叫者可以选择在None
上爆炸。
答案 3 :(得分:4)
不是一个单一的功能,但你可以很容易地做到:
>>> 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
答案 4 :(得分:2)
亚历克斯答案的一个变种。这样可以避免每次要使用X
或任何谓词
is_odd
>>> 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
答案 5 :(得分:1)
你可以用列表理解来做到这一点:
l = [8,10,4,5,7]
filterl = [a for a in l if a % 2 != 0]
然后filterl将返回列表的所有成员,表达式为%2!= 0.我会说更优雅的方法......