Bir python listesindeki tüm öğelere mantıksal bir operatör nasıl uygulanır


93

Python'da bir boole listem var. Onları VE (veya VEYA veya DEĞİL) yapmak ve sonucu almak istiyorum. Aşağıdaki kod işe yarıyor ama çok pitonik değil.

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

Nasıl daha pitonik olacağına dair herhangi bir öneri.

Yanıtlar:


181

andTüm öğelerde mantıksal a_list:

all(a_list)

orTüm öğelerde mantıksal a_list:

any(a_list)

Kendinizi yaratıcı hissediyorsanız şunları da yapabilirsiniz:

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)

bunların kısa devrede değerlendirilmediğini, yerleşiklerin ise ;-)

başka bir komik yol:

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

ve bir başkası:

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

ve bütün gün devam edebiliriz, ama evet, pitonik yol kullanmaktır allve any:-)

Bu arada, Python'da kuyruk özyineleme eliminasyonu yoktur, bu yüzden doğrudan LISP kodunu çevirmeye çalışmayın ;-)


8
operator.and_ bitsel ve operatördür &, mantıksal ve değil.
Karıncalar Aasma

1
şans eseri True ve False (işlemin istediği gibi) sırasıyla 1 ve 0'a dönüştürülür, bu nedenle bitsel operatörler mantıksal ^ _ ^
fortran

6
Pek çok gereksiz sürümü açıkladı, ancak gerçek doğru yanıt için sözdizimi sağlamadı.
jwg

2
ne istersen katılmıyorsun, SSS'de var: stackoverflow.com/privileges/vote-down
fortran

2
Not reduce()içindedir functoolsPython 3.0 beri
Duncan WP

33

ANDing ve ORing kolaydır:

>>> 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

NOT almak da oldukça kolaydır:

>>> [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]

Elbette, bu sonuçları nasıl kullanacağınız, DeMorgan teoreminin bazı ilginç uygulamalarını gerektirebilir.


4
Değil varyantı kısa devre yapmak istiyorsanız, basitçe oluşturucu ifadeleri kullanın: all(not x for x in some_list)(ama bu aynı not any(some_list)(oldukça doğal bir ifade, ha?)).
u0b34a0f6ae

16

Azaltmak bunu yapabilir:

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

Fortran'ın da bahsettiği gibi, bunu yapmanın en özlü yolu her şeydir. Ancak yanıtları azaltın daha genel bir soru olan "Bir python listesindeki tüm öğelere mantıksal bir operatör nasıl uygulanır?"


4
azaltmak uzaklaşmıyor, AFAIK. global ad alanındaki önceki konumundan functools modülüne taşınıyor
Eli Bendersky

1
@eliben: Neden Python 3'ten gelecek zamanda bahsedelim? azaltma hala orada . reduceolduğu functools.reduce Python 3'te
u0b34a0f6ae

Öğesini kaldırırsanız , True, bu yanıt, boole olmayan listeler için sorunun koduna gerçekten eşdeğer olan tek yanıt olacaktır.
Thomas Ahle

10

Bu tür işlemlerin deyimi, reduceişlevin (Python 2.X'te global, Python 3.X'teki modülde functools) operatormodülden alınan veya açıkça kodlanan uygun bir ikili operatörle kullanılmasıdır . Senin durumundaoperator.and_

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

4

İşte başka bir çözüm:

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

def my_or(a_list):
    return True in a_list

ANDing tüm öğeler True döndürür, eğer tüm öğeler True ise, bu nedenle listede False olmaz. ORing benzerdir, ancak bir listede en az bir True değeri varsa True döndürmelidir.


0

Diğer yanıtların gösterdiği gibi, bu görevi gerçekleştirmenin birden fazla yolu vardır. Standart kitaplıktaki işlevleri kullanan başka bir çözüm:

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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.