我有一个清单:
data_list = ['a.1','b.2','c.3']
我想只检索以另一个列表中的字符串开头的字符串:
test_list = ['a.','c.']
a.1
和c.3
应该返回。
我想我可以使用双循环:
for data in data_list:
for test in test_list:
if data.startswith(test):
# do something with item
我想知道是否有更优雅的东西,也许还有更多的信息。
答案 0 :(得分:12)
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 )
答案 1 :(得分:3)
只需将filter
与lambda function和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']
答案 2 :(得分:2)
尝试以下方法:
for data in data_list:
if any(data.startswith(test) for test in test_list):
# do something
any()
是一个内置函数,它接受一个可迭代的函数,然后返回来自bool为true的iterable的第一个值的True
,否则返回False
。在我的例子中,我使用的是生成器表达式,而不是构建列表(这会浪费)。
答案 3 :(得分:1)
>>> 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']
答案 4 :(得分: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中,并且可能比其他解决方案更有效。对于没有经验的人来说,这可能有点棘手。