繁体   English   中英

在 Python 中,如何检查一个数组是否包含另一个数组/列表的所有元素,包括重复项?

[英]In Python, how can I check if an array contains all elements of another array/list, including duplicates?

似乎有几种方法可以确定一个集合是否是另一个集合的子集,但我无法找到简洁的方法来确定列表(或数组)的所有元素(包括重复值)是否出现在另一个列表中(或数组)。 例如,对于假设的 function contains_all(A, B)检查B的所有元素是否包含在A中,这些是一些预期的输出:

contains_all([11, 4, 11, 6], [6, 11])返回True (顺序无关紧要)

contains_all([11, 4, 11, 6], [11, 9])返回False (否 9)

contains_all([11, 4, 11, 6], [11, 11])返回True

contains_all([11, 4, 11, 6], [11, 11, 11])返回False (只有两个 11)

contains_all([11, 4, 11, 6], [6, 6])返回False (只有一个 6)

contains_all([11, 4, 11, 6], [11, 4, 6, 11])返回True

contains_all([11, 4, 11, 6], [11, 4, 11, 6, 5])返回False (没有 5)

具体来说,上面的第四个和第五个示例是我在实施时遇到的问题。 set(B).issubset(A)或列表推导涵盖了其他情况,但不包括这些,因为集合没有重复的元素。 有没有一种简洁的方法来做到这一点? 如果不是,那么编写这样的 function 的最佳方法是什么? collections.Counter 对象或多重集似乎可能会发生这样的事情,但我不确定如何 go 来解决它。

在 Python 3.10 中, collections.Counter内置了以下功能:

def contains_all(A, B):
    return Counter(A) >= Counter(B)

但是,由于支持负计数, >=需要遍历两个 counter 中的所有键,当您知道所有计数都是非负数时,这是低效的。 手动检查 B 计数器中的键(如Guy 的回答)应该更快。 (我手边没有 Python 3.10,所以我无法提供时间。)

你是对的, collections.Counter是 go 的好方法。 您只需要通过B计数器 go 并检查该值是否小于或等于。 all()中执行以检查所有键值对

def contains_all(a, b):
    counter_a = Counter(a)
    counter_b = Counter(b)
    return all(v <= counter_a[k] for k, v in counter_b.items())

编辑

user2357112 的答案要好得多,但适用于 Pyton3.10 或更高版本。 对于旧版本,您可以使用此答案。

尝试这个

def contains(A, B):
contains_all = []
data_missing = []
for i in B:
    if i in A and B.count(i) <= A.count(i):
        contains_all.append(i)
    else:
        data_missing.append(i)
if data_missing:
    return False
else:
    return True

>>> print(contains([11, 4, 11, 6], [11, 4, 11, 6, 5]))
>>> False

暂无
暂无

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

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