2009-06-23 25 views
9

Tôi đang tìm một phương pháp đơn giản để kiểm tra xem chỉ một biến trong danh sách các biến có giá trị True hay không. Tôi đã xem xét điều này logical xor post và đang cố gắng tìm cách để thích ứng với nhiều biến và chỉ một sự thật.Kiểm tra xem chỉ một biến trong danh sách các biến được đặt là

Ví dụ

>>>TrueXor(1,0,0) 
True 

>>>TrueXor(0,0,1) 
True 

>>>TrueXor(1,1,0) 
False 

>>>TrueXor(0,0,0,0,0) 
False 

Trả lời

16

Không có một xây dựng trong nhưng nó không khó để cuộn bạn sở hữu:

def TrueXor(*args): 
    return sum(args) == 1 

Vì "[b] ooleans là một subtype của đồng bằng số nguyên "(source), bạn có thể tổng hợp danh sách các số nguyên khá dễ dàng và bạn cũng có thể chuyển các boolean thực vào hàm này.

Vì vậy, hai cuộc gọi đây là đồng nhất:

TrueXor(1, 0, 0) 
TrueXor(True, False, False) 

Nếu bạn muốn chuyển đổi boolean rõ ràng: sum(bool(x) for x in args) == 1.

+0

Tôi thích điều này - có thể bạn có thể cập nhật nó để chuyển đổi arg sang bool một cách rõ ràng? –

+2

Tôi nghĩ rằng bạn có nghĩa là để viết '' sum (bool (a) cho một trong args) == 1'' - các biến tự có thể không được booleans. – elo80ka

+0

Tôi chỉ yêu một lót. Tôi mới học được điều gì đó mới mẻ về những kẻ ngu ngốc. – Deon

3
>>> def f(*n): 
...  n = [bool(i) for i in n] 
...  return n.count(True) == 1 
... 
>>> f(0, 0, 0) 
False 
>>> f(1, 0, 0) 
True 
>>> f(1, 0, 1) 
False 
>>> f(1, 1, 1) 
False 
>>> f(0, 1, 0) 
True 
>>> 
1

Câu hỏi bạn đã liên kết đến đã cung cấp giải pháp cho hai biến. Tất cả những gì bạn phải làm là mở rộng để làm việc trên các biến số:

import operator 

def only_one_set(*vars): 
    bools = [bool(v) for v in vars] 
    return reduce(operator.xor, bools, False) 

>>> a, b, c, d, e = False, '', [], 10, -99 
>>> only_one_set(a, b, c, d) 
True 
>>> only_one_set(a, b, c, d, e) 
False 
+1

Như thường lệ, giảm là một người bạn giả: điều này thực sự kiểm tra nếu có một số ODD của các giá trị đúng - nó sẽ chỉ là hạnh phúc với 7 hoặc 77 những người như chỉ với 1! –

+0

Bạn nói đúng ... mặc dù tôi đoán đổ lỗi sẽ nhiều hơn về logic lỗi của tôi hơn là 'giảm'. Cảm ơn đã chỉ ra điều đó. – elo80ka

1

Đây là cách tiếp cận đơn giản của tôi. Tôi đã đổi tên nó thành only_one kể từ khi xor với nhiều hơn một đầu vào thường là một kiểm tra chẵn lẻ, không phải là một "chỉ một" kiểm tra.

def only_one(*args): 
    result = False 
    for a in args: 
     if a: 
      if result: 
       return False 
      else: 
       result = True 
    return result 

Thử nghiệm:

>>> only_one(1,0,0) 
True 
>>> only_one(0,0,1) 
True 
>>> only_one(1,1,0) 
False 
>>> only_one(0,0,0,0,0) 
False 
>>> only_one(1,1,0,1) 
False 
7

Tôi nghĩ rằng giải pháp tổng hợp dựa là tốt cho các ví dụ được đưa ra, nhưng hãy nhớ rằng boolean vị từ trong python luôn ngắn mạch đánh giá của họ. Vì vậy, bạn có thể muốn xem xét một cái gì đó phù hợp hơn với all and any.

def any_one(iterable): 
    it = iter(iterable) 
    return any(it) and not any(it) 
+1

Tuyệt. Bạn nên giải thích rằng 'không bất kỳ (nó)' hoạt động trên các phần còn lại của các mục còn lại bởi 'bất kỳ (nó)', cho những người không thoải mái với các trình vòng lặp. – tzot

+0

Có một cuộc thảo luận lành mạnh về cách sử dụng này tại đây: http://stackoverflow.com/a/16801605/4403872 và tại đây: http://stackoverflow.com/a/16522290/4403872 – vk1011

Các vấn đề liên quan