4

我有一个清单:

data_list = ['a.1','b.2','c.3']

我只想检索以另一个列表中的字符串开头的字符串:

test_list = ['a.','c.']

a.1并且c.3应该被退回。

我想我可以使用双 for 循环:

for data in data_list:
    for test in test_list:
       if data.startswith(test):
           # do something with item

我想知道是否有更优雅,也许更高效的东西。

4

5 回答 5

13

str.startswith也可以采用前缀的元组(但不是列表):

test_tuple=tuple(test_list)
for data in data_list:
    if data.startswith(test_tuple):
        ...

这意味着一个简单的列表理解将为您提供过滤后的列表:

matching_strings = [ x for x in data_list if x.startswith(test_tuple) ]

或致电filter

import operator
f = operator.methodcaller( 'startswith', tuple(test_list) )
matching_strings = filter( f, test_list )
于 2013-06-09T00:10:20.467 回答
3

只需使用filterlambda函数startswith

data_list = ['a.1','b.2','c.3']
test_list = ('a.','c.')

result = filter(lambda x: x.startswith(test_list), data_list)

print(list(result))

输出:

['a.1', 'c.3']
于 2013-06-09T00:14:34.823 回答
2

尝试以下操作:

for data in data_list:
    if any(data.startswith(test) for test in test_list):
        # do something

any()是一个内置函数,它接受一个可迭代对象并True从可迭代对象中返回布尔值为真的第一个值,否则返回False. 在我的示例中,我使用的是生成器表达式,而不是构建列表(这将是浪费)。

于 2013-06-09T00:08:32.997 回答
1

查看filter和python 文档中的任何内容。

>>> data_list = ['a.1','b.2','c.3']
>>> test_list = ['a.','c.']
>>> new_list = filter(lambda x: any(x.startswith(t) for t in test_list), data_list)
>>> new_list
['a.1', 'c.3']

然后,您可以对new_list.

正如@Chepner 指出的那样,您还可以向 提供一个字符串元组startswith,所以上面的内容也可以写成:

>>> data_list = ['a.1','b.2','c.3']
>>> test_tuple = ('a.','c.')
>>> new_list = filter(lambda x: x.startswith(test_tuple), data_list)
>>> new_list
['a.1', 'c.3']
于 2013-06-09T00:09:04.260 回答
1

或者,打破正则表达式

import re
# build a pattern that matches any of the strings we are interested in 
pattern = re.compile('|'.join(map(re.escape, test_list))) 
# filter by matches
print filter(pattern.match, data_list)

这可能将最可能的转移到 C 中,并且可能比其他解决方案更有效。不过,对于没有经验的人来说,这可能有点棘手。

于 2013-06-09T00:20:59.507 回答