Python 检查字符串中是否有字符串

Python 检查字符串中是否有字符串,python,string,list,comparison,Python,String,List,Comparison,我有一个巨大的列表,其中包含许多字符串,如: ['xxxx','xx','xy','yy','x',......] 现在,我正在寻找一种有效的方法来删除另一个字符串中存在的所有字符串。例如,“xx”“x”适合于“xxxx” 由于数据集很大,我想知道是否有一种有效的方法来解决这个问题 如果a在b中: 完整代码:可能包含一些优化部分: for x in range(len(taxlistcomplete)): if delete == True: x = x - 1 delete

我有一个巨大的列表,其中包含许多字符串,如:

['xxxx','xx','xy','yy','x',......]
现在,我正在寻找一种有效的方法来删除另一个字符串中存在的所有字符串。例如,“xx”“x”适合于“xxxx”

由于数据集很大,我想知道是否有一种有效的方法来解决这个问题

如果a在b中:

完整代码:可能包含一些优化部分:

for x in range(len(taxlistcomplete)):
if delete == True:
    x = x - 1
    delete = False
for y in range(len(taxlistcomplete)):
    if taxlistcomplete[x] in taxlistcomplete[y]:
        if x != y:
            print x,y
            print taxlistcomplete[x]
            del taxlistcomplete[x]
            delete = True
            break
    print x, len(taxlistcomplete)
代码的更新版本:

for x in enumerate(taxlistcomplete):
if delete == True:
    #If element is removed, I need to step 1 back and continue looping.....
    delete = False
for y in enumerate(taxlistcomplete):
    if x[1] in y[1]:
        if x[1] != y[1]:
            print x[1],y[1]
            print taxlistcomplete[x]

            del taxlistcomplete[x[0]]
            delete = True
            break
print x, len(taxlistcomplete)
现在使用enumerate实现,只是现在我想知道这是否更有效,以及如何实现删除步骤,以便减少搜索

只是想一想

基本上是我想看到的

若元素不匹配列表中的任何其他元素,则将此元素写入文件。 因此,如果'xxxxx'不在'xx'、'xy'、'wfirfj'等中。。。打印/保存

一个新的简单版本,因为我不认为我可以进一步优化它无论如何

print 'comparison'

file = open('output.txt','a')

for x in enumerate(taxlistcomplete):
    delete = False
    for y in enumerate(taxlistcomplete):
        if x[1] in y[1]:
            if x[1] != y[1]:
                taxlistcomplete[x[0]] = ''
                delete = True
                break
    if delete == False:
        file.write(str(x))

使用列表理解——注意中的
——是解决问题的最快、更具python风格的方法:

[element for element in arr if 'xx' in element]
x在
中速度很快,但是对照列表中的所有其他字符串检查每个字符串将花费O(n^2)时间。与通过优化比较来减少几个周期不同,您可以通过使用不同的数据结构来实现巨大的节约,这样您就可以在一次查找中检查每个字符串:对于两千个字符串,这是两千次检查,而不是四百万次检查

有一种称为“前缀树”(或trie)的数据结构,允许您非常快速地检查字符串是否是您以前见过的某个字符串的前缀。谷歌。因为您还对在另一个字符串<代码> > <代码>中间出现的字符串感兴趣,请对表单“代码> x、x [ 1:]、x [ 2 ]、x [ 3:]、< /代码>等所有子字符串进行索引(因此:只有长度为<代码> n< /代码>的字符串>代码> N< /代码>子串)。也就是说,索引从位置0、1、2等开始并一直到字符串末尾的子字符串。这样,您就可以检查新字符串是否是索引中某个内容的初始部分

然后,您可以在O(n)时间内解决问题,如下所示:

  • 按长度递减的顺序排列字符串。这确保了任何字符串都不能是您尚未看到的内容的子字符串。因为您只关心长度,所以可以在O(n)时间内进行桶排序

  • 从一个空的前缀树开始,并在有序的字符串列表上循环。对于每个字符串
    x
    ,使用前缀树检查它是否是您以前见过的字符串的子字符串。如果不是,则将其子字符串
    x,x[1:],x[2:
    等添加到前缀树中

  • 在长列表中间删除是非常昂贵的,因此如果收集要保留到新列表中的字符串(实际字符串不被复制,仅引用),则将获得进一步的加速。完成后,删除原始列表和前缀树


    如果这对你来说太复杂了,至少不要把每件事都和每件事做比较。按大小(按降序)对字符串进行排序,并仅将每个字符串与前面的字符串进行比较。这将给你一个50%的加速与非常小的努力。并且一定要做一个新的列表(或立即写入文件),而不是就地删除。

    以下是我的建议。首先,我按长度对元素进行排序。因为很明显,字符串越短,它越可能是另一个字符串的子字符串。然后我有两个for循环,在这里我遍历列表并从列表中删除每个元素,其中el是一个子字符串。请注意,第一个for循环只传递每个元素一次

    通过首先对列表进行排序,我们破坏了列表中元素的顺序。因此,如果顺序很重要,则不能使用此解决方案

    编辑。我假设列表中没有相同的元素。所以当el==el2时,是因为它是同一个元素

    a = ["xyy", "xx", "zy", "yy", "x"]
    a.sort(key=len)
    
    for el in a:
        for el2 in a:
            if el in el2 and el != el2:
                a.remove(el2)
    

    这里是一个简单的方法,假设您可以识别一个保证不在任何原始字符串中的字符(在我的示例中,我将使用
    '$'
    ):

    result = ''
    for substring in taxlistcomplete:
        if substring not in result: result += '$' + substring
    taxlistcomplete = result.split('$')
    

    这利用了Python对子字符串搜索的内部优化,只需将一个大字符串作为子字符串搜索:)

    字符串的顺序重要吗?请修复缩进,这不是有效的Python代码。不清楚您要做什么。将列表转换为集合,
    中的
    将更快。请注意,在列表长度范围内循环是非常不和谐的,循环值,如果需要索引,请使用
    enumerate()
    。顺序确实不相关,我只需要删除与其他项目部分匹配的所有项目。就像“茄子”中的“蛋”一样,蛋需要被移除。他想移除另一个元素(任何元素)中的所有元素。哦,似乎我没有理解,编辑之后就清楚了。然而,
    中的
    是检查一个字符串是否在另一个字符串中的最快方法。但这是确定列表中有多少字符串被该列表的其他元素包含的最快方法吗?问题是我将有861个元素(这是不正确的,但是重新检查需要一段时间。数字要高得多)如果我理解正确的话。Y确实被认为是XY的子串。因此,X和Y可以匹配XY,并且两者都将被删除。听起来可能不符合逻辑,但对于此数据集,它是:)删除元素最终也会加快搜索速度,因为要搜索的元素越来越少,对吧?在XY中匹配Y是有意义的,我只是希望得到一个简单的结果:-),但是删除不会对你有多大帮助,除非你的大多数字符串都是重复的。删除会很好,所以我最后有一个列表可以使用。或者我可以将不需要的元素重命名为“”,我的意思是,删除不会加快速度。无论如何,创建一个包含您想要保留的字符串的新列表通常比从列表中间删除大量字符串要快。