Làm thế nào để kiểm tra xem tất cả các mục sau đây có trong danh sách không?


114

Tôi nhận thấy rằng có một câu hỏi liên quan, về cách tìm xem có ít nhất một mục tồn tại trong danh sách hay không:
Làm thế nào để kiểm tra xem một trong các mục sau đây có trong danh sách không?

Nhưng cách tốt nhất và khó hiểu để tìm xem tất cả các mục có tồn tại trong một danh sách hay không?

Tìm kiếm trong 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 gõ nhiều hơn.

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


5
Có chuyện gì vậy set(smaller) <= set(larger)?
eumiro 14/10/10

1
Tôi nghĩ rằng giải pháp thứ hai của bạn với 'tất cả' trông rất ổn và khó hiểu đối với tôi.
Jiho Noh

Câu trả lời:


157

Các toán tử như <=trong Python thường không được ghi đè để có nghĩa là một cái gì đó khác biệt đáng kể so với "nhỏ hơn hoặc bằng". Thật không bình thường khi thư viện tiêu chuẩn thực hiện điều này - nó giống như API kế thừa đối với tôi.

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

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

2
không biết rằng bạn có thể chuyển danh sách trực tiếp dưới dạng đối số cho Issubset ... tốt đẹp!
tsimbalar 14/10/10

1
Mặc dù tôi đồng ý với tình cảm, nhưng tôi khá đồng ý với ý tưởng <=issubsetý nghĩa của điều tương tự. Tại sao bạn không thích nó?
Kirk Strauser 14/10/10

2
@Just: Chủ yếu, bởi vì không rõ ý <=nghĩa của một tập hợp mà không cần tra cứu trong tài liệu hoặc có kiến ​​thức trước về ý nghĩa của nó trong lý thuyết tập hợp, trong khi mọi người đều issubsettự động biết nghĩa của nó.
Glenn Maynard

2
Bạn biết toán tử toán học cho tập hợp con (không thích hợp)? nó về cơ bản trông khá giống như một tròn <=;)
dom0

yêu thích giải pháp này. có cách nào để lấy vị trí chỉ mục hoặc giá trị danh sách thay vì bool (Đúng: Sai) không?
Vlad Gulin

62

Tôi có thể sẽ sử dụng settheo cách sau:

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

Hoặc đường vòng khác :

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

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


Trên thực tế, MySet.issubset(MyOtherSet)MySet <= MyOtherSetđều giống nhau.
Wok

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

3
nó không thực sự khó hiểu nếu bạn nhớ lại việc bao gồm xác định một thứ tự từng phần trên bất kỳ tập hợp nào. Nó thực sự hơi khó hiểu khi <=có ý nghĩa mà nó mang lại cho các chuỗi: người ta có thể mong đợi nó có nghĩa là 'là một dãy con' chứ không phải là thứ tự từ vựng.
aaronasterling

1
@aaronasterling: mmm, tôi personnally không nghĩ quá nhiều về "trật tự một phần" khi tôi gõ mã :-), nhưng tôi đồng ý về một thực tế rằng việc sử dụng <=với trình tự cũng cảm thấy kỳ lạ, bằng cách nào đó ...
tsimbalar

3
Tôi gặp một chút vấn đề ở đây mà tôi muốn đề cập: Nếu bạn sử dụng phương pháp này, bạn đang chuyển đổi danh sách của mình thành tập hợp, có nghĩa là không có bản sao. set(['a','a']).issubset(['a'])lợi nhuận True.
Orangestar

11

Tôi thích hai cái này vì chúng có vẻ hợp lý nhất, cái sau ngắn hơn và có thể là nhanh nhất (được hiển thị ở đây bằng cách sử dụng setcú pháp theo nghĩa đen đã được hỗ trợ cho Python 2.7):

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

Giải pháp "tất cả" là nhanh nhất khi bạn đo nó bằng timeit (). Đây phải là câu trả lời được chấp nhận.
Attersson

3

Điều gì sẽ xảy ra nếu danh sách của bạn chứa các bản sao như thế này:

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)

1

Đây là những gì tôi đã tìm kiếm trực tuyến nhưng rất tiếc không tìm thấy trực tuyến nhưng trong khi thử nghiệm trên trình thông dịch python.

>>> case  = "caseCamel"
>>> label = "Case Camel"
>>> list  = ["apple", "banana"]
>>>
>>> (case or label) in list
False
>>> list = ["apple", "caseCamel"]
>>> (case or label) in list
True
>>> (case and label) in list
False
>>> list = ["case", "caseCamel", "Case Camel"]
>>> (case and label) in list
True
>>>

và nếu bạn có một danh sách các biến được lưu trữ trong một sublist variable

>>>
>>> list  = ["case", "caseCamel", "Case Camel"]
>>> label = "Case Camel"
>>> case  = "caseCamel"
>>>
>>> sublist = ["unique banana", "very unique banana"]
>>>
>>> # example for if any (at least one) item contained in superset (or statement)
...
>>> next((True for item in sublist if next((True for x in list if x == item), False)), False)
False
>>>
>>> sublist[0] = label
>>>
>>> next((True for item in sublist if next((True for x in list if x == item), False)), False)
True
>>>
>>> # example for whether a subset (all items) contained in superset (and statement)
...
>>> # a bit of demorgan's law
...
>>> next((False for item in sublist if item not in list), True)
False
>>>
>>> sublist[1] = case
>>>
>>> next((False for item in sublist if item not in list), True)
True
>>>
>>> next((True for item in sublist if next((True for x in list if x == item), False)), False)
True
>>>
>>>

0

Ví dụ về cách thực hiện việc này bằng cách sử dụng biểu thức lambda sẽ là:

issublist = lambda x, y: 0 in [_ in x for _ in y]

1
Hãy thêm nhận xét để giải thích / xây dựng câu trả lời của bạn
Sharad

0

Không trường hợp OP, nhưng - cho những ai muốn đến ngã tư khẳng định trong dicts và kết thúc ở đây do googling nghèo (ví dụ như tôi) - bạn cần phải làm việc với dict.items:

>>> a = {'key': 'value'}
>>> b = {'key': 'value', 'extra_key': 'extra_value'}
>>> all(item in a.items() for item in b.items())
True
>>> all(item in b.items() for item in a.items())
False

Đó là bởi vì dict.itemstrả về bộ giá trị của các cặp khóa / giá trị và giống như bất kỳ đối tượng nào trong Python, chúng có thể so sánh được với nhau

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.