2010-10-14 34 views
53

tôi thấy rằng có liên quan câu hỏi, về làm thế nào để tìm thấy nếu ít nhất một mục tồn tại trong một danh sách:
How to check if one of the following items is in a list?Cách kiểm tra xem tất cả các mục sau có nằm trong danh sách không?

Nhưng cách tốt nhất và pythonic để tìm xem tất cả các mục tồn tại trong danh sách là gì?

Tìm kiếm thông qua các tài liệu tôi tìm thấy giải pháp này:

>>> l = ['a', 'b', 'c'] 
>>> set(['a', 'b']) <= set(l) 
True 
>>> set(['a', 'x']) <= set(l) 
False 

giải pháp khác sẽ là:

>>> l = ['a', 'b', 'c'] 
>>> all(x in l for x in ['a', 'b']) 
True 
>>> all(x in l for x in ['a', 'x']) 
False 

Nhưng ở đây bạn phải làm đánh máy hơn.

Có giải pháp nào khác không?

+4

Có gì sai với 'set (nhỏ hơn) <= set (large)'? – eumiro

Trả lời

42

Các nhà khai thác như <= trong Python thường không được ghi đè để có nghĩa là khác biệt đáng kể so với "ít hơn hoặc bằng ". Nó không bình thường đối với các thư viện chuẩn thực hiện điều này - nó có mùi giống như API cũ đối với tôi.

Sử dụng phương thức tương đương và được đặt tên rõ ràng hơn, set.issubset. Lưu ý rằng bạn không cần chuyển đổi đối số thành tập hợp; nó sẽ làm điều đó cho bạn nếu cần thiết.

set(['a', 'b']).issubset(['a', 'b', 'c']) 
+2

không biết bạn có thể vượt qua danh sách trực tiếp như một đối số để issubset ... tốt đẹp! – tsimbalar

+0

Trong khi tôi đồng ý với tình cảm, tôi khá OK với ý tưởng '<=' và 'issubset' có nghĩa là giống nhau. Tại sao bạn không thích nó? –

+2

@Just: Chủ yếu, bởi vì nó không rõ ràng những gì '<=' có nghĩa là cho một bộ mà không cần tìm kiếm trong tài liệu hoặc có kiến ​​thức trước về ý nghĩa trong lý thuyết tập, trong khi mọi người biết 'issubset' có nghĩa là gì. –

49

tôi có lẽ sẽ sử dụng set theo cách sau đây:

set(l).issuperset(set(['a','b'])) 

hoặc theo chiều ngược lại:

set(['a','b']).issubset(set(l)) 

Tôi tìm thấy nó dễ đọc hơn một chút, nhưng nó có thể là quá kill. Các bộ đặc biệt hữu ích để tính toán liên minh/giao lộ/sự khác biệt giữa các bộ sưu tập, nhưng nó có thể không phải là lựa chọn tốt nhất trong tình huống này ...

+0

Trên thực tế, 'MySet.issubset (MyOtherSet)' và 'MySet <= MyOtherSet' giống nhau. – Wok

+1

@wok: oh Tôi không biết điều đó, nhưng tôi nghĩ cú pháp <= hơi khó hiểu vì cú pháp tương tự có thể được sử dụng với các danh sách, nhưng với một ý nghĩa rất khác. – tsimbalar

+2

nó không thực sự là khó hiểu nếu bạn nhớ lại bao gồm xác định một phần đơn đặt hàng trên bất kỳ tập hợp các bộ.Nó thực sự hơi khó hiểu rằng '<=' có ý nghĩa của nó đối với chuỗi: người ta có thể mong đợi nó có nghĩa là 'là một chuỗi' thay vì thứ tự từ điển. – aaronasterling

4

Tôi thích hai bởi vì họ có vẻ là hợp lý nhất, sau này là ngắn hơn và có lẽ nhanh nhất (hiển thị ở đây sử dụng Set Literals mới mà đã backported để Python 2.7):

all(x in {'a', 'b', 'c'} for x in ['a', 'b']) 
# or 
{'a', 'b'}.issubset({'a', 'b', 'c'}) 
1

gì nếu bạn danh sách chứa các từ khóa trùng lặp như sau:

v1 = ['s', 'h', 'e', 'e', 'p'] 
v2 = ['s', 's', 'h'] 

Bộ không chứa trùng lặp. Vì vậy, dòng sau trả về True.

set(v2).issubset(v1) 

Để đếm các bản sao, bạn có thể sử dụng mã:

v1 = sorted(v1) 
v2 = sorted(v2) 


def is_subseq(v2, v1): 
    """Check whether v2 is a subsequence of v1.""" 
    it = iter(v1) 
    return all(c in it for c in v2) 

Vì vậy, dòng sau trả về False.

is_subseq(v2, v1) 
Các vấn đề liên quan