我想取列表x和y的差值:
>>> x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> y = [1, 3, 5, 7, 9]
>>> x - y
# should return [0, 2, 4, 6, 8]
我想取列表x和y的差值:
>>> x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> y = [1, 3, 5, 7, 9]
>>> x - y
# should return [0, 2, 4, 6, 8]
当前回答
试试这个。
def subtract_lists(a, b):
""" Subtracts two lists. Throws ValueError if b contains items not in a """
# Terminate if b is empty, otherwise remove b[0] from a and recurse
return a if len(b) == 0 else [a[:i] + subtract_lists(a[i+1:], b[1:])
for i in [a.index(b[0])]][0]
>>> x = [1,2,3,4,5,6,7,8,9,0]
>>> y = [1,3,5,7,9]
>>> subtract_lists(x,y)
[2, 4, 6, 8, 0]
>>> x = [1,2,3,4,5,6,7,8,9,0,9]
>>> subtract_lists(x,y)
[2, 4, 6, 8, 0, 9] #9 is only deleted once
>>>
其他回答
其他解决方案都存在以下几个问题之一:
它们不能维持秩序,或者 它们不删除精确的元素计数,例如,对于x =[1,2,2,2]和y =[2,2],它们将y转换为一个集合,然后删除所有匹配的元素(只留下[1])或删除每个唯一元素中的一个(留下[1,2,2]),当正确的行为是删除2两次,留下[1,2],或者 它们做O(m * n)个功,而最优解做O(m + n)个功
Alain和Counter在解决第2和第3个问题上是正确的,但这个解决方案将失去秩序。保持顺序的解决方案(在要删除的值列表中重复n次,删除每个值的前n个副本)是:
from collections import Counter
x = [1,2,3,4,3,2,1]
y = [1,2,2]
remaining = Counter(y)
out = []
for val in x:
if remaining[val]:
remaining[val] -= 1
else:
out.append(val)
# out is now [3, 4, 3, 1], having removed the first 1 and both 2s.
在网上试试!
要使它删除每个元素的最后副本,只需将for循环改为for val in reversed(x):并在退出for循环后立即添加out.reverse()。
根据y的长度构造Counter为O(n),根据x的长度迭代x为O(n), Counter隶属度测试和突变为O(1),而list。append被平摊为O(1)(一个给定的append可以是O(n),但对于许多追加,整体大O平均为O(1),因为越来越少的追加需要重新分配),所以所做的总体功是O(m + n)。
你还可以通过测试来确定y中是否有任何元素没有从x中移除:
remaining = +remaining # Removes all keys with zero counts from Counter
if remaining:
# remaining contained elements with non-zero counts
这个例子减去了两个列表:
# List of pairs of points
list = []
list.append([(602, 336), (624, 365)])
list.append([(635, 336), (654, 365)])
list.append([(642, 342), (648, 358)])
list.append([(644, 344), (646, 356)])
list.append([(653, 337), (671, 365)])
list.append([(728, 13), (739, 32)])
list.append([(756, 59), (767, 79)])
itens_to_remove = []
itens_to_remove.append([(642, 342), (648, 358)])
itens_to_remove.append([(644, 344), (646, 356)])
print("Initial List Size: ", len(list))
for a in itens_to_remove:
for b in list:
if a == b :
list.remove(b)
print("Final List Size: ", len(list))
我们也可以使用set方法来查找两个列表之间的差异
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
y = [1, 3, 5, 7, 9]
list(set(x).difference(y))
[0, 2, 4, 6, 8]
from collections import Counter
y = Counter(y)
x = Counter(x)
print(list(x-y))
试试这个。
def subtract_lists(a, b):
""" Subtracts two lists. Throws ValueError if b contains items not in a """
# Terminate if b is empty, otherwise remove b[0] from a and recurse
return a if len(b) == 0 else [a[:i] + subtract_lists(a[i+1:], b[1:])
for i in [a.index(b[0])]][0]
>>> x = [1,2,3,4,5,6,7,8,9,0]
>>> y = [1,3,5,7,9]
>>> subtract_lists(x,y)
[2, 4, 6, 8, 0]
>>> x = [1,2,3,4,5,6,7,8,9,0,9]
>>> subtract_lists(x,y)
[2, 4, 6, 8, 0, 9] #9 is only deleted once
>>>