【问题标题】:How to subtract a list from a list? [duplicate]如何从列表中减去列表? [复制]
【发布时间】:2021-05-27 06:36:39
【问题描述】:

我正在尝试编写一个从列表中减去列表的代码。

例如:

list1 = ['hi', 'hi', 'once', 'twice']
list2 = ['hi', 'once', 'twice']

减去我想要的列表的结果是:

differenceoflists = ['hi']

目前,我正在使用代码

list1 = ['hi', 'hi', 'once', 'twice']
list2 = ['hi', 'once', 'twice']
differenceoflists = []
for i in list1:
    if i not in list2:
        differenceoflists.append(i)
print(differenceoflists)

但是,此代码无法按我希望的方式运行。当我希望它返回['hi'] 时,它会返回一个空列表。我怎样才能正确地做到这一点?

【问题讨论】:

  • 但是'hi'list2中,所以它不能在differenceoflists中。为什么会这样?
  • 嗯,list1 中有两个 hi,list2 中只有一个,所以我希望代码计算 list1 中的额外 hi。
  • 它返回一个空列表,因为 list2 中的同一个 'hi' 被匹配了两次。根据您的性能和输出限制,您可能可以使用您的想法,除了使用 list2 的 副本 工作,并在将它们添加到 differenceoflists 时使用 .remove(item) 从 list2 中删除内容.

标签: python list


【解决方案1】:

这也可以使用collections.Counter 来完成,您可以从彼此中减去计数器,然后将结果变成一个列表:

from collections import Counter

list1 = ['hi', 'hi', 'once', 'twice']
list2 = ['hi', 'once', 'twice']

difference_of_lists = list((Counter(list1) - Counter(list2)).elements())

print(difference_of_lists)

['hi']

【讨论】:

  • 您可以调用Counter 对象的elements 方法将其转换为列表,而不是使用生成器表达式重新发明轮子。
【解决方案2】:

您的代码无法正常工作,因为它没有跟踪多久来自list2 的项目被用于丢弃来自list1 的相应项目。

您可以从list1 的副本开始创建differenceoflists,而不是通过添加 个项目并删除 list2 中的所有项目。这样一来,对应的项目对只匹配一次,如果 list1 中包含的项目比 list2 中包含的项目更多,则附加项将保留。

要从列表中删除项目,您可以使用remove 方法。当您尝试删除的项目不在列表中时,您需要处理这种情况(只需忽略它)。

def differenceoflists(list1, list2):
    d = list1.copy()
    for i in list2:
        try:
            d.remove(i)
        except ValueError:
            pass  # ignore that i is not in list1
    return d

将此代码与Jab's answer 中显示的代码进行比较时,结果中包含的项目的顺序存在一些细微差别。根据您的具体需求,您需要选择其中之一。

differenceoflists 删除左侧项目,differenceoflists_jab 删除右侧项目:

>>> differenceoflists([1, 3, 5, 1], [5, 1])
[3, 1]
>>> differenceoflists([1, 3, 5, 1], [1, 5])
[3, 1]
>>> differenceoflists_jab([1, 3, 5, 1], [5, 1])
[1, 3]
>>> differenceoflists_jab([1, 3, 5, 1], [1, 5])
[1, 3]

differenceoflists_jab 不保留list1 中项目的顺序:

>>> differenceoflists([1, 3, 5, 1], [5])
[1, 3, 1]
>>> differenceoflists_jab([1, 3, 5, 1], [5])
[1, 1, 3]

【讨论】:

  • 谢谢!如果您不使用“尝试”,它会起作用吗?
  • 不,如果list2 中有一个项目不在list1 中,尝试删除它会引发ValueError 异常。
  • 有道理,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多