如何在列表中查找项目的索引,在 Python 中使用正则表达式搜索项目?

Posted

技术标签:

【中文标题】如何在列表中查找项目的索引,在 Python 中使用正则表达式搜索项目?【英文标题】:How to find an index of an item in a list, searching the item with a regular expression in Python? 【发布时间】:2011-09-30 18:52:27 【问题描述】:

我有一个这样的列表:

lst = ['something', 'foo1', 'bar1', 'blabla', 'foo2']

是否可以使用正则表达式和lst.index() 获取以“foo”(foo1)开头的第一项的索引,例如:

ind = lst.index("some_regex_for_the_item_starting_with_foo") ?

我知道我可以创建一个计数器和一个 for 循环并使用方法 startswith()。 如果我错过了一些更短更优雅的方式,我很好奇。

【问题讨论】:

【参考方案1】:

我认为没关系,如果它执行您真正想要的操作,您可以使用startswith 方法(我不确定您是否真的需要regEx - 但是可以轻松修改下面的代码以使用regEx):

data = ['text', 'foo2', 'foo1', 'sample']
indeces = (i for i,val in enumerate(data) if val.startswith('foo'))

或者使用正则表达式:

from re import match
data = ['text', 'foo2', 'foo1', 'sample']
indeces = (i for i,val in enumerate(data) if match('foo', val))

【讨论】:

【参考方案2】:

使用lst.index 无法做到这一点,但是这里有一种替代方法,您可能会发现它比 for 循环更优雅:

try:
    ind = (i for i, v in enumerate(lst) if v.startswith("foo")).next()
except StopIteration:
    ind = -1   # or however you want to say that the item wasn't found

正如 senderle 在评论中指出的,这可以通过使用带有默认值的 next() 内置函数 (2.6+) 将其缩短为一行:

ind = next((i for i, v in enumerate(lst) if v.startswith("foo")), -1)

【讨论】:

【参考方案3】:

不,很遗憾,list.index 没有 key 参数。 有一个解决方案可能是

# warning: NOT working code
result = L.index(True, key=lambda x: regexp.match(x) is not None)

此外,鉴于我刚刚发现 lambda 显然在 python 社区中被认为是可憎的,我不确定将来是否会添加更多 key 参数。

【讨论】:

你不认为key 没有 lambda 有用吗?以operator.itemgetter 为例?我也很好奇谁认为lambda 是可憎的。当然,它可能真的很难看,但我认为它是语言的重要组成部分,尤其是当你有一个不能完全完成你想要的内置函数时。 @senderle: 是的key 可以用于其他情况,但在许多常见情况下,使用小的匿名闭包非常适合key。关于为什么 lambda 如此讨厌,我最近(在 EuroPython)发现了这一点,我问为什么在一个例子中 function.Partial 被用于应该是 lambda 的工作的案例中,Alex Martelli 回答 >。更多解释请参见***.com/q/3252228/320726 谢谢,这为我解决了问题。我认为这是(对我而言)实用性胜过纯度的情况。不过,我看到了 AM 的一面。如果lambda 被删除,我想我不会哭(太难了)。【参考方案4】:

内置这样的东西会很酷。但Python没有。使用 itertools 有一些有趣的解决方案。 (这些也让我希望有一个itertools.takewhile_false。如果它存在,这些将更具可读性。)

>>> from itertools import takewhile
>>> import re
>>> m = re.compile('foo.*')
>>> print len(tuple(itertools.takewhile(lambda x: not m.match(x), lst)))
1

这是我的第一个想法,但它需要您创建一个临时元组并获取它的长度。然后我想到你可以只做一个简单的求和,而避免使用临时列表:

>>> print sum(1 for _ in takewhile(lambda x: not m.match(x), lst))
1

但这也有点麻烦。我更喜欢尽可能避免丢弃的变量。让我们再试一次。

>>> sum(takewhile(bool, (not m.match(x) for x in lst)))
1

好多了。

【讨论】:

您的解决方案非常特别,同时也不太可读,但是我明白了您所做的。我想使用“not”而不是使用函数 takewhile_false 更自然。同样的事情是如果有一个while_false循环而不是“while smth != smth2” 我在 itertools 中找到了“dropwhile”。我想这就是你所说的“takewhile_false” @rightaway717,不,dropwhile 丢弃项直到谓词为真,然后取出其余的,就像takewhile 取出直到谓词为真并丢弃其余的项。换句话说,给定相同的迭代和谓词,takewhile 将产生列表的第一部分,dropwhile 将产生列表的第二部分。 抱歉,这很糟糕,您正在构建一个元组(可能很大)只是为了计算索引? @alexis,嗯,这就是我改进第一个版本的原因,如果你阅读了整篇文章,你肯定已经看到了。更高版本不创建元组。我想sum 可能会在内部构建一个元组——在这种情况下,我必须对sum 的实现提出异议。【参考方案5】:
l = ['something', 'foo1', 'bar1', 'blabla', 'foo2']
l.index(filter(lambda x:x.startswith('foo'),l)[0])

【讨论】:

我会记住这个解决方案。我刚开始学习python,并不知道它与“i for i,val in ...”的含义相同。现在我知道了。感谢您的努力

以上是关于如何在列表中查找项目的索引,在 Python 中使用正则表达式搜索项目?的主要内容,如果未能解决你的问题,请参考以下文章

Python:在浮动列表中查找最小项目的索引[重复]

python 在Python中查找包含它的列表的项目的索引

如何在python列表中查找某个元素的索引

如何在python列表中查找某个元素的索引

如何在python列表中查找某个元素的索引

python 查找列表中项目的索引