如何检查字符串是否包含Python中列表中的元素


217

我有这样的事情:

extensionsToCheck = ['.pdf', '.doc', '.xls']

for extension in extensionsToCheck:
    if extension in url_string:
        print(url_string)

我想知道在Python中(不使用for循环)更优雅的方法是什么?我在想这样的事情(例如从C / C ++开始),但是没有用:

if ('.pdf' or '.doc' or '.xls') in url_string:
    print(url_string)

编辑:我有点被迫解释这与下面的问题有何不同,该问题被标记为潜在重复(所以我猜它不会关闭)。

区别是,我想检查一个字符串是否是某些字符串列表的一部分,而另一个问题是检查字符串列表中的字符串是否是另一个字符串的子字符串。类似的,但不完全相同,当您在网上寻找答案时,语义很重要。这两个问题实际上是在寻求解决彼此相反的问题。两者的解决方案虽然相同。


Answers:


418

与一起使用发电机any,它会在第一个True上短路:

if any(ext in url_string for ext in extensionsToCheck):
    print(url_string)

编辑:我看到这个答案已经被OP接受。尽管我的解决方案可能是解决他特定问题的“足够好”的解决方案,并且是检查列表中是否有任何字符串在另一个字符串中找到的一种很好的通用方法,但请记住,这就是该解决方案的全部工作。不管在哪里找到字符串,例如在字符串的末尾。如果这很重要(通常是使用url的情况),则应查看@Wladimir Palant的答案,否则,您可能会得到误报。


1
这正是我想要的。在我的情况下,扩展名在字符串中的哪个位置都没有关系。谢谢
pootzko 2011年

很棒的建议。使用此示例,这就是我检查是否有任何参数与众所周知的帮助标志相匹配的方式:any([[x.lower()in ['-?','-h','-help','/ h '] for sys.argv [1:]]中的x)
AX Labs

@ AXE-Labs在内部使用列表推导any会否定短路可能带来的一些好处,因为在每种情况下都必须构建整个列表。如果使用不带方括号(any(x.lower() in ['-?','-h','--help', '/h'] for x in sys.argv[1:]))的表达式,x.lower() in [...]则仅对零件求值,直到找到True值为止。
Lauritz V. Thaulow 2014年

5
如果我想知道当any()返回True时ext是什么?
彼得·塞纳

@PeterSenna:any()只会返回truefalse,但请使用以下修改查看@psun的列表理解答案:print [extension for extension in extensionsToCheck if(extension in url_string)]
Dannid

45
extensionsToCheck = ('.pdf', '.doc', '.xls')

'test.doc'.endswith(extensionsToCheck)   # returns True

'test.jpg'.endswith(extensionsToCheck)   # returns False

5
这很聪明-我不知道元组可以做到这一点,但是只有当您的子字符串锚定到字符串的一端时,它才起作用。
丹妮德

3
太酷了 我只是希望有一个类似“包含”的东西,而不仅仅是开头或结尾
BrDaHa

@BrDaHa您可以在包含中使用'in'。如果列表中为“字符串”:
Shekhar Samanta,

@ShekharSamanta可以肯定,但这并不能解决检查字符串中是否包含多个对象之一的问题,这是原始问题所在。
BrDaHa

是的,在这种情况下,我们可以使用:if any(string.split('any delmiter')用于列表中的元素)和string如果存在(string.split用于列表中的元素的元素)
Shekhar Samanta

21

这是更好地解析正确的URL -这种方式,您可以处理http://.../file.doc?foohttp://.../foo.doc/file.exe正确。

from urlparse import urlparse
import os
path = urlparse(url_string).path
ext = os.path.splitext(path)[1]
if ext in extensionsToCheck:
  print(url_string)

3

如果需要单行解决方案,请使用列表推导。以下代码在扩展名为.doc,.pdf和.xls时返回包含url_string的列表,或者在不包含扩展名时返回空列表。

print [url_string for extension in extensionsToCheck if(extension in url_string)]

注意:这仅是检查它是否包含,并且在想要提取与扩展名匹配的确切单词时无用。


这比any解决方案更具可读性,在我看来,这是针对该问题的最佳解决方案之一。
德米特里·维霍图洛夫'16

这一个是优于any()在我看来,解决方案,因为它可以改变返回特定的匹配值,以及像这样:print [extension for extension in extensionsToCheck if(extension in url_string)](见我的回答更多的细节以及如何提取匹配的单词以及从URL_STRING模式)
丹妮德

2

检查它是否与此正则表达式匹配:

'(\.pdf$|\.doc$|\.xls$)'

注意:如果扩展名不在URL的末尾,请删除$字符,但这会稍微削弱它


1
这是一个URL,如果有查询字符串怎么办?
弗拉基米尔·帕兰特

import re re.search(pattern,your_string)
juankysmith 2011年

虽然此答案适用于指定情况,但它不是可伸缩的或通用的。您需要为每个要匹配的模式使用一个长的正则表达式。
丹妮德

1

这是@psun给出的列表理解答案的一种变体。

通过切换输出值,您实际上可以从列表理解中提取匹配的模式(any()@ Lauritz-v-Thaulow 的方法无法做到这一点)

extensionsToCheck = ['.pdf', '.doc', '.xls']
url_string = 'http://.../foo.doc'

print [extension for extension in extensionsToCheck if(extension in url_string)]

['.doc']`

如果想要在知道匹配的模式后收集其他信息,则可以进一步插入正则表达式(当允许的模式列表太长而无法写入单个regex模式时,这可能会很有用)

print [re.search(r'(\w+)'+extension, url_string).group(0) for extension in extensionsToCheck if(extension in url_string)]

['foo.doc']

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.