ban*_*ana 48 python indexing function list
该list.index(x)
函数返回值为的第一个项的列表中的索引x
.
是否有一个函数,list_func_index()
类似于index()
具有函数的函数f()
,作为参数.该函数在列表的f()
每个元素上运行e
,直到 f(e)
返回True
.然后list_func_index()
返回索引e
.
Codewise:
>>> 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
Run Code Online (Sandbox Code Playgroud)
有更优雅的解决方案吗?(以及该功能的更好名称)
Pau*_*aul 86
您可以使用生成器在单行中执行此操作:
next(i for i,v in enumerate(l) if is_odd(v))
Run Code Online (Sandbox Code Playgroud)
关于生成器的好处是它们只能计算到所需的数量.因此,请求前两个索引(几乎)同样简单:
y = (i for i,v in enumerate(l) if is_odd(v))
x1 = next(y)
x2 = next(y)
Run Code Online (Sandbox Code Playgroud)
但是,期望在最后一个索引之后出现StopIteration异常(这就是生成器的工作方式).这在你的"先取"方法中也很方便,要知道没有找到这样的值--- list.index()函数会抛出ValueError.
Ale*_*lli 12
@保罗接受的答案是最好的,但这里有一个侧面思维的变体,主要用于娱乐和教学目的......:
>>> 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
Run Code Online (Sandbox Code Playgroud)
本质上,其X
目的是将"相等"的含义从正常的"改变为满足此谓词",从而允许在各种情况下使用谓词,这些情境被定义为检查相等性 - 例如,它会也让你编码,而不是if any(is_odd(x) for x in l):
更短if X(is_odd) in l:
,等等.
值得使用?当@Paul采用的更明确的方法同样方便时(特别是当改为使用新的,闪亮的内置next
函数而不是旧的,不太合适的.next
方法时,正如我在对该答案的评论中所建议的那样),但是在其他情况下(或者其他变体的想法"调整平等的含义",也许其他比较器和/或散列)可能是合适的.大多数情况下,值得了解这个想法,以避免有一天从头开始发明它;-).
Jon*_*erg 11
一种可能性是内置的枚举函数:
def index_of_first(lst, pred):
for i,v in enumerate(lst):
if pred(v):
return i
return None
Run Code Online (Sandbox Code Playgroud)
通常将您描述的函数称为"谓词"; 某些问题会返回true或false.这就是我pred
在我的例子中称之为的原因.
我也认为返回会有更好的形式None
,因为这是问题的真正答案.None
如果需要,呼叫者可以选择爆炸.
不是一个单一的函数,但你可以在 Python 2 中非常轻松地完成它:
>>> test = lambda c: c == 'x'
>>> data = ['a', 'b', 'c', 'x', 'y', 'z', 'x']
>>> map(test, data).index(True)
3
Run Code Online (Sandbox Code Playgroud)
如果您不想立即评估整个列表,您可以使用 itertools,但它并不那么漂亮:
>>> from itertools import imap, ifilter
>>> from operator import itemgetter
>>> ifilter(itemgetter(1), enumerate(imap(test, data))).next()[0]
3
Run Code Online (Sandbox Code Playgroud)
仅使用生成器表达式可能比不过更具可读性itertools
。
注意在Python3中,map
返回filter
惰性迭代器,你可以使用:
>>> from operator import itemgetter
>>> next(filter(itemgetter(1), enumerate(map(test, data))))[0]
3
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
44985 次 |
最近记录: |