假设我有一个未知对象的列表L
,O1
到On
,我想删除另一个对象引用M
可能引用L
中的一个对象,我已设法使用:
L = [ O1, O2, ... On]
...
L = [ j for j in L if j not in [ M ] ]
这是可爱和惯用的...但我必须做很多事情,我想知道是否有其他更惯用的方式,或者是否有更快的方式。
重点是对象列表未知,可能或可能包含要排除的对象。我想避免在可能的情况下扩展或子类化对象。
答案 0 :(得分:5)
list.remove
似乎是最快的方式,列表理解速度最快,最后filter
。
以下是timeit
结果
In: python -m timeit '[x for x in [1,2,3,4,5] if x not in [4]]'
Out: 1000000 loops, best of 3: 0.285 usec per loop
In: python -m timeit '[x for x in [1,2,3,4,5] if x != 4]'
Out: 1000000 loops, best of 3: 0.254 usec per loop
In: python -m timeit 'filter(lambda x: x not in [4], [1,2,3,4,5])'
Out: 1000000 loops, best of 3: 0.577 usec per loop
In: python -m timeit 'filter(lambda x: x != 4, [1,2,3,4,5])'
Out: 1000000 loops, best of 3: 0.569 usec per loop
In: python -m timeit '[1,2,3,4,5].remove(4)'
Out: 10000000 loops, best of 3: 0.132 usec per loop
答案 1 :(得分:2)
内置filter功能怎么样?
>>> l = [1,2,3,4,5]
>>> f = [4]
>>> filter(lambda x: x not in f, l)
[1, 2, 3, 5]
或在python3中
>>> list(filter(lambda x: x not in f, l))
[1, 2, 3, 5]
答案 2 :(得分:2)
使用包含在递归函数中的try
/ except
递归处理潜在的多个M
def tremove(L, M):
try:
L.remove(M)
return tremove(L, M)
except:
return L
tremove(L, M)
答案 3 :(得分:2)
如果您的值出现多次,那么可能需要while
- 循环remove
:
L = [1,2,3,4,5]
while True:
try:
L.remove(4)
except:
break
与列表理解相比,它有点慢(由于异常处理和列表上的多次迭代):
[ j for j in L if j != 4 ]
但两者都做得很好。如果要排除多个值,则应使用list-comprehension:
M = [1, 4]
[ j for j in L if j not in M ]
因为try
/ except
将被嵌套,列表推导只需要遍历列表一次。
答案 4 :(得分:2)
这是一个想法,让你对可以清洗的物品进行O(1)遏制检查。对于包含大量哈希值的长列表M
,它应该会快得多。
class MixedBag(object):
def __init__(self, *args):
self.hashed = set()
self.nothashed = []
for x in args:
self.add(x)
def add(self, x):
try:
self.hashed.add(x)
except TypeError:
self.nothashed.append(x)
def __contains__(self, x):
try:
return x in self.hashed
except TypeError:
return x in self.nothashed
L = [[1,2,3], 4, '5', {6}]
M = [[1,2,3], '5', {4}]
mix = MixedBag(*M)
L = [x for x in L if x not in mix]
print(L) # [4, set([6])]