在列表中搜索子字符串的Pythonic方式

4

我有一个字符串列表 - 类似于以下内容:

mytext = ['This is some text','this is yet more text','This is text that contains the substring foobar123','yet more text']

我想找到以foobar开头的任何内容的第一次出现。如果我在使用grep命令,那么我会搜索foobar*。我的当前解决方案如下:

for i in mytext:
    index = i.find("foobar")
    if(index!=-1):
        print i

这样做是可以的,但我想知道有没有更好(即更符合Python风格)的方法?

谢谢, Mike


2
你的代码和注释不一致。 :) 你说你想要“以foobar开头的任何东西”(因此@THC4k的答案),但是你的代码打印包含“foobar”的任何字符串(因此其他人的答案)。 - pilcrow
同意 - 我在措辞问题时不够小心。但我不会更正它,这样未来的人们就可以看到我是愚蠢的那一个,而不是那些回答我的人。对不起,各位,感谢你们所有的回答。 - WalkingRandomly
5个回答

16

你也可以使用列表推导式:

matches = [s for s in mytext if 'foobar' in s]

如果你真的在寻找以 'foobar' 开头的字符串,可以考虑以下方法:

matches = [s for s in mytext if s.startswith('foobar')]

现在我在想,将其作为生成器是否更好:matches = (s for s in mytext if s.startswith('foobar')) 有人知道吗? - Koen Bok
1
@Koen 如果(a)结果列表很大(尽管它只包含对原始字符串的引用),并且(b)您不需要一次性获得结果,例如进行len(matches)或matches[-1],而是想要迭代它,则最好使用生成器。 - ThomasH

10
如果您真的想要以foobar开头的字符串的第一个出现(这是您的话所说的,尽管与您的代码非常不同,所有提供的答案,您提到的grep - 多么矛盾?-),请尝试:
found = next((s for s in mylist if s.startswith('foobar')), '')

如果mylist没有任何一项符合条件,则此代码将返回空字符串作为found结果。您还可以使用itertools等替代简单的genexp,但关键技巧是使用具有默认值的内置next的方式(仅适用于Python 2.6及更高版本)。


+1 我刚才在琢磨一个(s for s in...)[0]表达式,想要获取第一个元素,不过如果没有第一个元素该怎么办…… - ThomasH
@ThomasH,在2.5版本中,你必须这样做:try: / x=blah.next() / except StopIteration,而2.6的内置函数next更加方便! - Alex Martelli

6
for s in lst:
    if 'foobar' in s:
         print(s)

5
results = [ s for s in lst if 'foobar' in s]
print(results)

4

如果您真的正在寻找以foobar开头(而不是在其中包含foobar)的字符串:

for s in mylist:
  if s.startswith( 'foobar' ):
     print s

或者
found = [ s for s in mylist if s.startswith('foobar') ]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接