Як застосувати логічний оператор до всіх елементів у списку python


89

У мене є список логічних типів у python. Я хочу І (або АБО чи НІ) їх і отримати результат. Наступний код працює, але не дуже пітонічний.

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

Будь-які пропозиції щодо того, як зробити його більш пітонічним, буде вдячний.

Відповіді:


175

Логічний andдля всіх елементів у a_list:

all(a_list)

Логічний orдля всіх елементів у a_list:

any(a_list)

Якщо ви відчуваєте творчість, ви також можете зробити:

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)

майте на увазі, що вони не оцінюються в короткому замиканні, в той час як вбудовані є ;-)

ще один кумедний спосіб:

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

і ще одне:

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

і ми могли б продовжувати весь день, але так, пітонічний спосіб полягає у використанні allта any:-)

До речі, Python не має усунення рекурсії хвоста, тому не намагайтеся перекладати код LISP безпосередньо ;-)


8
operator.and_ є побітовим оператором і оператором &, а не логічним і.
Ants Aasma

1
на щастя True та False (як бажано в операційній системі) відлічуються відповідно до 1 та 0, тому побітові оператори працюють як логічні ^ _ ^
fortran

6
Пояснив багато зайвих версій, але не надав синтаксис фактичної правильної відповіді.
jwg

2
не погоджуйся, що хочеш, це у FAQ: stackoverflow.com/privileges/vote-down
fortran

2
Зауважте, що reduce()це functoolsпочинається з Python 3.0
Duncan WP

33

ANDing та ORING дуже прості:

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

Звичайно, як би ви використовували ці результати, може знадобитися кілька цікавих застосувань теореми ДеМоргана.


4
Якщо ви хочете скоротити не варіант, просто використовуйте генераторські вирази: all(not x for x in some_list)(але це те саме, що not any(some_list)(цілком природний вираз, так?)).
u0b34a0f6ae

16

Зменшення може зробити це:

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

Як згадував Фортран, це найкоротший спосіб зробити це. Але зменшіть відповіді на більш загальне питання "Як застосувати логічний оператор до всіх елементів у списку пітонів?"


4
зменшення не зникає, AFAIK. його переміщують у модуль functools з попередньої позиції у глобальному просторі імен
Елі Бендерскі,

1
@eliben: Навіщо говорити про Python 3 у майбутньому часі? зменшити все ще є . reduceзнаходиться functools.reduce в Python 3
u0b34a0f6ae

Якщо видалити , True, ця відповідь буде єдиною, що насправді еквівалентна коду запитання для небулевих списків.
Thomas Ahle

10

Ідіомою таких операцій є використання reduceфункції (глобальної в Python 2.X, в модулі functoolsв Python 3.X) з відповідним двійковим оператором, або взятим з operatorмодуля, або кодованим явно. У вашому випадку це такoperator.and_

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

4

Ось ще одне рішення:

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

def my_or(a_list):
    return True in a_list

ANDing всіх елементів поверне True, якщо всі елементи True, отже, у списку немає False. ORing подібний, але він повинен повертати True, якщо в списку є хоча б одне True значення.


0

Як показують інші відповіді, існує багато способів виконати це завдання. Ось ще одне рішення, яке використовує функції зі стандартної бібліотеки:

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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.