如何从字符串列表中检索部分匹配项

ves*_*and 19 python string list filter

有关在数字列表中检索部分匹配项的方法,请访问:


但是,如果您正在寻找如何检索字符串列表的部分匹配项,您会在下面的答案中找到简明扼要地解释的最佳方法。

SO:部分匹配的 Python 列表查找显示了如何返回 a bool,如果 alist包含部分匹配(例如beginsends, 或contains)某个字符串的元素。但是你怎么能返回元素本身,而不是TrueFalse

例子:

l = ['ones', 'twos', 'threes']
wanted = 'three'
Run Code Online (Sandbox Code Playgroud)

在这里,链接问题中的方法将返回True使用:

any(s.startswith(wanted) for s in l)
Run Code Online (Sandbox Code Playgroud)

那么如何返回元素'threes'呢?

Tre*_*ney 23

  • startswithin, 返回一个布尔值
  • in运营商成员的考验。
  • 这可以用一个list-comprehensionfilter
  • 使用list-comprehension, 和in是经过测试的最快实现。
  • 如果大小写不是问题,请考虑将所有单词映射为小写。
    • l = list(map(str.lower, l)).

filter

  • Usingfilter创建一个filter对象,所以list()用于显示list.
l = ['ones', 'twos', 'threes']
wanted = 'three'

# using startswith
result = list(filter(lambda x: x.startswith(wanted), l))

# using in
result = list(filter(lambda x: wanted in x, l))

print(result)
[out]:
['threes']
Run Code Online (Sandbox Code Playgroud)

list-comprehension

l = ['ones', 'twos', 'threes']
wanted = 'three'

# using startswith
result = [v for v in l if v.startswith(wanted)]

# using in
result = [v for v in l if wanted in v]

print(result)
[out]:
['threes']
Run Code Online (Sandbox Code Playgroud)

哪个实现更快?

  • 使用words语料库来自nltk
  • 词与 'three'
    • ['three', 'threefold', 'threefolded', 'threefoldedness', 'threefoldly', 'threefoldness', 'threeling', 'threeness', 'threepence', 'threepenny', 'threepennyworth', 'threescore', 'threesome']
from nltk.corpus import words

%timeit list(filter(lambda x: x.startswith(wanted), words.words()))
[out]:
47.4 ms ± 1.9 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit list(filter(lambda x: wanted in x, words.words()))
[out]:
27 ms ± 1.78 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit [v for v in words.words() if v.startswith(wanted)]
[out]:
34.1 ms ± 768 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit [v for v in words.words() if wanted in v]
[out]:
14.5 ms ± 63.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Run Code Online (Sandbox Code Playgroud)


dam*_*mon 8

any()您可以使用 for 循环来查找字符串,而不是返回函数的结果:

def find_match(string_list, wanted):
    for string in string_list:
        if string.startswith(wanted):
            return string
    return None

>>> find_match(['ones', 'twos', 'threes'], "three")
'threes'
Run Code Online (Sandbox Code Playgroud)


Ste*_*eve 8

一个简单直接的答案:

test_list = ['one', 'two','threefour']
r = [s for s in test_list if s.startswith('three')]
print(r[0] if r else 'nomatch')
Run Code Online (Sandbox Code Playgroud)

结果:

threefour
Run Code Online (Sandbox Code Playgroud)

不确定在不匹配的情况下您想做什么。 r[0]如果有匹配项,这正是您所要求的,但如果没有匹配项,则它是未定义的。在print这一交易,但你可能会想这样做是不同的。


sup*_*ain 6

我会说最密切相关的解决方案是使用next而不是any

>>> next((s for s in l if s.startswith(wanted)), 'mydefault')
'threes'
>>> next((s for s in l if s.startswith('blarg')), 'mydefault')
'mydefault'
Run Code Online (Sandbox Code Playgroud)

就像 一样any,它在找到匹配项后立即停止搜索,并且只占用 O(1) 空间。与列表理解解决方案不同,它总是处理整个列表并占用 O(n) 空间。

哦,或者any按原样使用,但记住最后检查的元素:

>>> if any((match := s).startswith(wanted) for s in l):
        print(match)

threes
>>> if any((match := s).startswith('blarg') for s in l):
        print(match)

>>>
Run Code Online (Sandbox Code Playgroud)

另一种变体,仅分配匹配元素:

>>> if any(s.startswith(wanted) and (match := s) for s in l):
        print(match)

threes
Run Code Online (Sandbox Code Playgroud)

(可能想要包含诸如or True匹配项s是否可以是空字符串之类的内容。)


Iro*_*key 5

这对我来说似乎很简单,所以我可能误读了,但你可以通过带有 if 语句的 foo 循环运行它;

l = ['ones', 'twos', 'threes']
wanted = 'three'

def run():
    for s in l:
        if (s.startswith(wanted)):
            return s

print(run())
Run Code Online (Sandbox Code Playgroud)

输出: threes


归档时间:

查看次数:

8382 次

最近记录:

4 年,7 月 前