Trả về boolean nếu bộ trống


97

Tôi đang đấu tranh để tìm một cách rõ ràng hơn để trả về giá trị boolean nếu tập hợp của tôi trống ở cuối hàm của tôi

Tôi lấy phần giao nhau của hai tập hợp và muốn trả về Truehoặc Falsedựa trên nếu tập hợp kết quả là trống.

def myfunc(a,b):
    c = a.intersection(b)
    #...return boolean here

Suy nghĩ ban đầu của tôi là làm

return c is not None

Tuy nhiên, trong trình thông dịch của tôi, tôi có thể dễ dàng thấy rằng câu lệnh sẽ trả về true nếu c = set([])

>>> c = set([])
>>> c is not None
True

Tôi cũng đã thử tất cả những cách sau:

>>> c == None
False
>>> c == False
False
>>> c is None
False

Bây giờ tôi đã đọc từ tài liệu mà tôi chỉ có thể sử dụng and, ornotvới bộ trống để suy ra một giá trị boolean. Cho đến nay, điều duy nhất tôi có thể nghĩ ra là trở về không phải là c

>>> not not c
False
>>> not c
True

Tôi có cảm giác có một cách hay ho hơn nhiều để làm điều này, bởi tôi đang đấu tranh để tìm ra nó. Tôi không muốn trả lại tập thực tế thành câu lệnh if vì tôi không cần các giá trị, tôi chỉ muốn biết liệu chúng có giao nhau hay không.


4
tập rỗng được coi là boolean False tương đương nếu bạn cast nó vậy:bool(set([]))
woozyking

3
nhân tiện, một câu hỏi được làm việc nghiêm túc, rất đáng chú ý.
Jonas Schäfer

@JonasWielicki Cảm ơn! Đánh giá cao câu trả lời - biết rằng đó là một cái gì đó dọc theo những dòng đó.
CB

Câu hỏi này sẽ kéo dài 5 năm và không ai đề xuất sử dụng isdisjoint. Tôi hoàn toàn bị sốc.
Adirio

Câu trả lời:


68
def myfunc(a,b):
    c = a.intersection(b)
    return bool(c)

bool()sẽ làm điều gì đó tương tự not not, nhưng lý tưởng và rõ ràng hơn.


7
Tôi phản đối, viết bool(...)khi bạn yêu cầu is_emptylà tối nghĩa. Tôi không bày tỏ ý định.
tamas.kenez

2
@ tamas.kenez Tuy nhiên, bạn phải thừa nhận rằng nó rõ ràng hơn not not;). (FTR: Tôi đã bỏ phiếu tán @gefeis câu trả lời, nhưng tôi không có ảnh hưởng đến điều OP chấp nhận ...)
Jonas Schäfer

108

không phải là pythonic như các câu trả lời khác, mà là toán học:

return len(c) == 0

Như một số ý kiến ​​thắc mắc về tác động len(set)có thể có đối với sự phức tạp. Nó là O (1) như được hiển thị trong mã nguồn vì nó dựa vào một biến theo dõi việc sử dụng tập hợp.

static Py_ssize_t
set_len(PyObject *so)
{
    return ((PySetObject *)so)->used;
}

9
Tôi nghĩ điều này thực sự tốt hơn. Nó làm cho nó rõ ràng hơn ý định của bạn là gì.
arshajii

4
Tôi e rằng điều này sẽ phải tính toán len(c)ngay cả khi crất lớn, điều này là không cần thiết để kiểm tra độ trống.
Michele De Pascalis

1
@Glaedr Tôi tin vào cpython len cho cấu trúc dữ liệu thường được sử dụng (tức là danh sách, tập hợp) là O (1) (tức là chúng lưu trữ một biến trên cấu trúc dữ liệu đại diện cho độ dài)
CB

2
^ +1 @CB Tôi đã thực hiện một số thử nghiệm trên len (c) và nó chắc chắn là một số biến đại diện cho len vì có sự khác biệt thời gian chạy không đáng kể khi kích thước thiết lập thay đổi thứ tự cường độ đáng kể.
dster77

1
@ dster77 i cấu hình mã của tôi với cả hai phiên bản và nó đã nhanh hơn đáng kể khi so sánh với set()(python 3.5.2 trong cửa sổ)
mathiasfk

23

Nếu bạn muốn return Truemột tập hợp trống, thì tôi nghĩ sẽ rõ ràng hơn khi làm:

return c == set()

tức là " cbằng một rỗng set".

(Hoặc, ngược lại, return c != set()).

Theo ý kiến ​​của tôi, điều này rõ ràng hơn (mặc dù ít thành ngữ hơn) so với việc dựa vào diễn giải của Python về một tập hợp rỗng như Falsetrong ngữ cảnh boolean.


2
Trên thực tế, dựa vào diễn giải của Python là một thực tiễn rất được chấp nhận. Miễn là những hạn chế của nó được ghi nhớ.
núi lửa

17

Nếu clà một tập hợp sau đó bạn có thể kiểm tra xem nó có sản phẩm nào bằng cách thực hiện: return not c.

Nếu ctrống thì not csẽ có True.

Ngược lại, nếu cchứa bất kỳ phần tử nào not csẽ được False.


6

Khi bạn nói:

c is not None

Bạn đang thực sự kiểm tra xem c và Không có tham chiếu cùng một đối tượng hay không. Đó là những gì toán tử "is" làm. Trong python None là một giá trị null đặc biệt theo quy ước có nghĩa là bạn không có sẵn một giá trị. Sắp xếp như null trong c hoặc java. Vì nội bộ python chỉ gán một giá trị None bằng cách sử dụng toán tử "is" để kiểm tra xem thứ gì đó là None (nghĩ là null) hoạt động hay không và nó đã trở thành kiểu phổ biến. Tuy nhiên, điều này không liên quan đến giá trị chân lý của tập hợp c, nó đang kiểm tra xem c thực sự là một tập hợp chứ không phải là một giá trị rỗng.

Nếu bạn muốn kiểm tra xem một tập hợp có trống trong câu lệnh điều kiện hay không, tập hợp đó được truyền dưới dạng boolean trong ngữ cảnh nên bạn chỉ cần nói:

c = set()
if c:
   print "it has stuff in it"
else:
   print "it is empty"

Nhưng nếu bạn muốn nó được chuyển đổi thành boolean để được lưu trữ, bạn chỉ cần nói:

c = set()
c_has_stuff_in_it = bool(c)

1
"""
This function check if set is empty or not.
>>> c = set([])
>>> set_is_empty(c)
True

:param some_set: set to check if he empty or not.
:return True if empty, False otherwise.
"""
def set_is_empty(some_set):
    return some_set == set()

0

Không sạch bằng bool (c) nhưng đó là một cái cớ để sử dụng ternary.

def myfunc(a,b):
    return True if a.intersection(b) else False

Cũng bằng cách sử dụng một chút logic tương tự, không cần gán cho c trừ khi bạn đang sử dụng nó cho việc khác.

def myfunc(a,b):
    return bool(a.intersection(b))

Cuối cùng, tôi giả sử bạn muốn một giá trị True / False vì bạn sẽ thực hiện một số loại kiểm tra boolean với nó. Tôi khuyên bạn nên bỏ qua phần chi phí của một lệnh gọi hàm và định nghĩa bằng cách đơn giản thử nghiệm ở nơi bạn cần.

Thay vì:

if (myfunc(a,b)):
    # Do something

Có lẽ điều này:

if a.intersection(b):
    # Do something
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.