Python: Xem một bộ có chứa hoàn toàn một bộ khác không?


82

Có cách nào nhanh chóng để kiểm tra xem một bộ hoàn toàn chứa bộ khác không?

Cái gì đó như:

>>>[1, 2, 3].containsAll([2, 1])
True

>>>[1, 2, 3].containsAll([3, 5, 9])
False

Câu trả lời:


125

Đó là những danh sách, nhưng nếu bạn thực sự muốn nói đến các tập hợp, bạn có thể sử dụng phương thức Issubset.

>>> s = set([1,2,3])
>>> t = set([1,2])
>>> t.issubset(s)
True
>>> s.issuperset(t)
True

Đối với một danh sách, bạn sẽ không thể làm tốt hơn việc kiểm tra từng phần tử.


3
Tôi nhận được một cảm giác kỳ lạ của DejaVu khi tôi nhìn thấy câu trả lời này
Christophe Roussy

bạn phải nhận thức được ý nghĩa của issubset()khôngcontains()
wikier

37

Đối với tính đầy đủ: điều này tương đương với issubset(mặc dù được cho là ít rõ ràng / dễ đọc hơn một chút):

>>> set([1,2,3]) >= set([2,1])
True
>>> set([1,2,3]) >= set([3,5,9])
False

Vấn đề là là a = set ([]) và b = set ([ 'a', 'b']) sau đó a.issubset (b) là True
darkman

4

Một tùy chọn được giữ nguyên - phép trừ:

>>> {1, 2} - {1, 2, 3}
set([])
>>> {1, 2, 3} - {1, 2}
set([3])

Về cơ bản, bạn kiểm tra những yếu tố nào trong danh sách đầu tiên không có trong danh sách thứ hai.

Tôi thấy nó rất hữu ích vì bạn có thể hiển thị những giá trị nào bị thiếu:

>>> def check_contains(a, b):
...     diff = a - b
...     if not diff:
...         # All elements from a are present in b
...         return True
...     print('Some elements are missing: {}'.format(diff))
...     return False
...
>>> check_contains({1, 2}, {1, 2, 3})
True
>>> check_contains({1, 2, 3}, {1, 2})
Some elements are missing: set([3])
False

3

Bạn có thể sử dụng set.issubset()hoặc set.issuperset()(hoặc các đối tác dựa trên toán tử của chúng: <=>=). Lưu ý rằng các phương thức sẽ chấp nhận mọi đối số có thể lặp lại , không chỉ là một tập hợp:

>>> {1, 2}.issubset([1, 2, 3])
True
>>> {1, 2, 3}.issuperset([1, 2])
True

Tuy nhiên, nếu bạn sử dụng toán tử, cả hai đối số phải là bộ:

>>> {1, 2} <= {1, 2, 3}
True
>>> {1, 2, 3} >= {1, 2}
True

3

Nếu bạn nghi ngờ một tập hợp là tập hợp con của tập hợp con khác và giao hai tập hợp đó với nhau, kết quả sẽ bằng chính nó nếu nó là tập hợp con.

a = [2,1,3,3]
b = [5,4,3,2,1]
set(a).intersection(set(b)) == set(a)
>>True

1
Hãy để A = set(a)B = set(b)cho sự tỉnh táo. Sau đó, sự so sánh này có thể giảm xuống một cách hiệu quả len(A.intersection(B)) == len(A). Có nghĩa là, bản thân các tập hợp không cần phải so sánh theo phần tử; chỉ cần so sánh bản số của các tập hợp này. Tuy nhiên, ngay cả sự tối ưu hóa này có lẽ là không đủ để làm cho phương pháp này trở nên thích hợp hơn. Các đột ngột dễ đọc hơn hiệu quả issubset()<=các cách tiếp cận là gần như chắc chắn những gì mọi người muốn.
Cecil Curry,

@CecilCurry True - Tôi đã sử dụng từ 'cardinality' không chính xác vì nó là một phép đo độ dài. Tôi đã cập nhật từ ngữ. Tối ưu hóa của bạn là một lỗi dựa trên lỗi của tôi. Không phải là một tối ưu hóa. Từ ngữ nghĩa đen của "giao điểm ()" đọc rõ ràng hơn so với hàm ý bị quá tải của "> =" và nói rằng "Issubset ()" dễ đọc hơn là loại bỏ điều hiển nhiên vì nó là câu trả lời phổ biến nhất. Hãy thoải mái đóng góp một giải pháp sáng tạo ngoài việc lặp lại câu trả lời của người khác.
Jordan Stefanelli

1
>>> set([1,2,3]).issuperset(set([2,1]))
True 
>>>    
>>> set([1,2,3]).issuperset(set([3,5,9]))
False

3
Cân nhắc để định dạng câu trả lời phù hợp và thêm một số giải thích.
Sam

0

Hàm bên dưới trả về 0 nếu danh sách chính không chứa đầy đủ danh sách con và 1 nếu chứa đầy đủ.

def islistsubset(sublist,mainlist):
     for item in sublist:
             if item in mainlist:
                     contains = 1
             else:
                     contains = 0
                     break;
     return contains

1
Đây là O (n ^ 2) trong khi sử dụng các phép toán tập hợp như trong một số câu trả lời hiện có nhanh hơn nhiều. Điều này cũng có thể được viết đơn giản any(item in mainlist for item in sublist).
Iguananaut

Đồng ý thông tin Tôi cũng có thể viết def islistsubset (danh sách phụ, danh sách chính): chứa = 1 cho mục trong danh sách phụ: nếu mục trong danh sách chính: tiếp tục else: chứa = 0 break; trở lại chứa Vì vậy, chỉ có 2 bài tập cho mỗi cuộc gọi
bobin Motti Thomas

@BobinMottiThomas Bạn có thể trực tiếp trả về True hoặc False mà không cần tạo bất kỳ biến tạm thời nào. cho mặt hàng trong list_a: nếu hàng không trong list_b: trở lại False Đúng
Jordan Stefanelli
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.