繁体   English   中英

删除 Python 列表中的类似项目

[英]Remove similar items in a list in Python

如何删除 Python 列表中的类似项目,但仅适用于给定项目。 例子,

l = list('need')

如果'e'是给定的项目,那么

l = list('nd')

set() function 不会成功,因为它会删除所有重复项。

count() 和 remove() 效率不高。

使用filter

假设您编写 function 来决定要保留在列表中的项目。

对于你的例子

 def pred(x):
     return x!="e"
 l=list("need")
 l=list(filter(pred,l))

假设given = 'e'l= list('need')

for i in range(l.count(given)):
    l.remove(given)

如果您只想从列表中的单词列表中替换'e' ,则可以使用正则表达式 re.sub()。 如果您还想计算从每个单词中删除了多少次 e,那么您可以使用 re.subn()。 第一个将为您提供列表中的字符串。 第二个将为您提供一个元组 (string, n),其中 n 是出现次数。

import re
lst = list(('need','feed','seed','deed','made','weed','said'))
j = [re.sub('e','',i) for i in lst]
k = [re.subn('e','',i) for i in lst]

j 和 k 的 output 是:

j = ['nd', 'fd', 'sd', 'dd', 'mad', 'wd', 'said']
k = [('nd', 2), ('fd', 2), ('sd', 2), ('dd', 2), ('mad', 1), ('wd', 2), ('said', 0)]

如果您想计算所做的总更改,只需遍历 k 并将其相加即可。 还有其他更简单的方法。 您可以简单地使用正则表达式

re.subn('e','',''.join(lst))[1]

这将为您提供列表中替换的项目总数。

List comprehension方法。 不确定大小/复杂性是否小于countremove

def scrub(l, given):
    return [i for i in l if i not in given]

过滤方法,我也不确定

def filter_by(l, given):
    return list(filter(lambda x: x not in given, l))

具有recursion的蛮力,但有很多潜在的失败。 还是一个选择。 再次,我不知道大小/comp

def bruteforce(l, given):
    try:
        l.remove(given[0])
        return bruteforce(l, given)
    except ValueError:
        return bruteforce(l, given[1:])
    except IndexError:
        return l
    return l

对于那些对与上述方法相关的实际时间感到好奇的人,我冒昧地在下面测试它们!

以下是我选择使用的方法。

def timer(func, name):
    print("-------{}-------".format(name))
    try:
        start = datetime.datetime.now()
        x = func()
        end = datetime.datetime.now()
        print((end-start).microseconds)
    except Exception, e:
        print("Failed: {}".format(e))
    print("\r")

我们正在测试的数据集。 其中l是我们的原始列表, q是我们要删除的项目, r是我们的预期结果。

l = list("need"*50000)
q = list("ne")
r = list("d"*50000)

对于后代,我添加了 OP 反对的count / remove方法。 (有充分的理由!)

def count_remove(l, given):
    for i in given:
        for x in range(l.count(i)):
            l.remove(i)
    return l

剩下要做的就是测试!

timer(lambda: scrub(l, q), "List Comp")
assert(scrub(l,q) == r)

timer(lambda: filter_by(l, q), "Filter")
assert(filter_by(l,q) == r)

timer(lambda : count_remove(l, q), "Count/Remove")
assert(count_remove(l,q) == r)

timer(lambda: bruteforce(l, q), "Bruteforce")
assert(bruteforce(l,q) == r)

而我们的结果

-------列表比较-----
10000

- - - -筛选 - - - -
28000

--------计数/删除-----
199000

--------蛮力-----
失败:超出最大递归深度

进程以退出代码 0 结束

Recursion方法在更大的数据集上失败了,但我们预料到了这一点。 我在较小的数据集上进行了测试, Recursion速度稍慢。 我以为会更快。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM