2009-11-24 42 views
46

Tôi có danh sách các boolean trong python. Tôi muốn VÀ (hoặc HOẶC hoặc KHÔNG) họ và nhận được kết quả. Các mã sau đây hoạt động nhưng không phải là rất pythonic.Cách áp dụng toán tử logic cho tất cả các phần tử trong danh sách python

def apply_and(alist): 
if len(alist) > 1: 
    return alist[0] and apply_and(alist[1:]) 
else: 
    return alist[0] 

Bất kỳ đề xuất nào về cách làm cho nó được đánh giá cao hơn.

Trả lời

105

logic and trên tất cả các yếu tố trong a_list:

all(a_list) 

logic or trên tất cả các yếu tố trong a_list:

any(a_list) 

Nếu bạn cảm thấy sáng tạo, bạn cũng có thể làm:

import operator 
def my_all(a_list): 
    return reduce(operator.and_, a_list, True) 

def my_any(a_list): 
    return reduce(operator.or_, a_list, False) 

ghi nhớ rằng những người không được đánh giá trong ngắn mạch, trong khi xây dựng-in là ;-)

một cách hài hước:

def my_all_v2(a_list): 
    return len(filter(None,a_list)) == len(a_list) 

def my_any_v2(a_list): 
    return len(filter(None,a_list)) > 0 

nhưng khác:

def my_all_v3(a_list): 
    for i in a_list: 
    if not i: 
     return False 
    return True 

def my_any_v3(a_list): 
    for i in a_list: 
    if i: 
     return True 
    return False 

và chúng tôi có thể đi cả ngày, nhưng có, cách pythonic là sử dụng allany :-)

Bởi wa y, Python có không đuôi loại bỏ đệ quy, do đó, không cố gắng để dịch mã LISP trực tiếp ;-)

+7

toán tử.and_ là bitwise và toán tử &, không phải là logic và. –

+1

may mắn Đúng và Sai (như op muốn) được đúc thành 1 và 0 tương ứng, vì vậy các toán tử bitwise hoạt động như logic^_^ – fortran

+0

Đáng chú ý ... 2.5+ nhưng rất dễ để backport. –

10

Reduce thể làm điều này:

reduce(lambda a,b: a and b, alist, True) 

Như fortran đề cập, tất cả là cách cô đọng nhất để làm nó. Nhưng giảm câu trả lời cho câu hỏi tổng quát hơn "Cách áp dụng toán tử logic cho tất cả các phần tử trong danh sách python?"

+4

giảm không biến mất, AFAIK. nó đang được chuyển vào mô-đun functools, từ vị trí trước đó của nó trong không gian tên toàn cầu –

+1

@eliben: Tại sao lại nói về Python 3 trong tương lai? * giảm vẫn còn đó *. 'reduce' là' functools.reduce' * trong Python 3 * – u0b34a0f6ae

+0

Nếu bạn xóa ', True', câu trả lời này sẽ là câu trả lời duy nhất thực sự tương đương với mã của câu hỏi, đối với các danh sách không phải là boolean. –

31

ANDing và ORing là dễ dàng:

>>> some_list = [True] * 100 
# OR 
>>> any(some_list) 
True 
#AND 
>>> all(some_list) 
True 
>>> some_list[0] = False 
>>> any(some_list) 
True 
>>> all(some_list) 
False 

chú ý cũng khá đơn giản:

>>> [not x for x in some_list] 
[True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] 

Tất nhiên, làm thế nào bạn sẽ sử dụng những kết quả đó có thể đòi hỏi một số ứng dụng thú vị của định lý DeMorgan của.

+4

Nếu bạn muốn ngắn mạch của biến thể không, chỉ cần sử dụng biểu thức máy phát điện: 'tất cả (không x cho x trong some_list)' (nhưng đó là giống như 'không bất kỳ (some_list)' (khá một biểu hiện tự nhiên, huh?)). – u0b34a0f6ae

0

Như các câu trả lời khác cho thấy, có nhiều cách để thực hiện tác vụ này. Đây là một giải pháp có sử dụng chức năng từ các thư viện chuẩn:

from functools import partial 

apply_and = all 
apply_or = any 
apply_not = partial(map, lambda x: not x) 

if __name__ == "__main__": 
    ls = [True, True, False, True, False, True] 
    print "Original: ", ls 
    print "and: ", apply_and(ls) 
    print "or: ", apply_or(ls) 
    print "not: ", apply_not(ls) 
7

Các thành ngữ cho các hoạt động như vậy là để sử dụng chức năng reduce (toàn cầu trong Python 2.x, trong mô-đun functools bằng Python 3.x) với một nhị phân thích hợp toán tử được lấy từ mô-đun operator hoặc được mã hóa một cách rõ ràng.Trong trường hợp của bạn, đó là operator.and_

reduce(operator.and_, [True, True, False]) 
2

Dưới đây là một giải pháp khác:

def my_and(a_list): 
    return not (False in a_list) 

def my_or(a_list): 
    return True in a_list 

ANDing tất cả các yếu tố sẽ trở lại True nếu tất cả các yếu tố này là True, vì thế không sai trong một danh sách. ORing tương tự, nhưng nó phải trả về True nếu có ít nhất một giá trị True có trong danh sách.

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