2016-12-20 1 views
2

Existe-t-il un moyen de comparer les éléments de liste et de renvoyer la valeur de résultat? Ci-dessous l'extrait Python, où il reçoit deux valeurs et renvoie la valeur.Comment effectuer des opérations logiques OU sur une liste [plusieurs éléments]?

def logical_or_decision(a,b): 
    return a or b 

value = logical_or_decision(1,0) 
print value 

je dois rendre générique & évolutive à plus de 2 elements.How je peux le faire pour plus de 2 éléments?

+0

Voulez-vous revenir strictement'on' ou 'false', ou (en cas de' or') la première valeur truthy de la liste, comme 'a ou b ou c ou ...' serait ? –

Répondre

4

Il existe une fonction intégrée qui fait ceci: any.

>>> any([0,0,1,0]) 
True 

>>> any([0,0,0]) 
False 
+2

Et le "et" équivalent 'tout'. –

+0

et s'il y a 3 éléments comme celui-ci 0,1, -1? disons que j'ai une liste de [0, -1], il devrait retourner -1. si [0,0, -1], il devrait retourner -1 – Jackie

+0

@Jackie que représente -1? Quelles autres entrées utilisez-vous? –

2

Vous pouvez utiliser reduce pour le faire:

def logical_or_decision(*args): 
    return reduce(
     lambda a, b: a or b, 
     args, 
     False 
    ) 

print logical_or_decision(1, 1, 1, 0) # False 

Bien sûr, vous pouvez utiliser any ou all (pour AND logique), mais reduce pourrait vous fournir la manière générale de construire de telles opérations (non pour OR ou AND).

+0

Vous pouvez l'utiliser avec les opérateurs disponibles dans le module ['operator'] (https://docs.python.org/2/library/operator.html#operator.or_) plutôt que d'utiliser' lambda'. –

+0

@AshwiniChaudhary Notez que 'operator.or_' est' | ', pas' ou'. –

+0

@tobias_k Oops! ma faute. –

0

La fonction builtin any() serait la bonne façon d'aller à ce sujet:

def logical_or_decision(*args): 
    return any(args) 

value = logical_or_decision(1, 0, 0, 1, 0, 0) 
print value 

La partie pertinente du lien vers la documentation officielle ci-dessus:

Retour True si un élément du itérable est vrai. Si l'itérable est vide, renvoyez False. Équivalent à:

def any(iterable): 
    for element in iterable: 
     if element: 
      return True 
    return False 
2
meilleure solution

^^ ^^ ci-dessus:

any([True, False, True]) 
# returns True 

any est bon parce que "les courts-circuits" (comme "une évaluation rapide booléenne" il n'itérer pas jusqu'à ce que le fin).

Si vous voulez que les choses semblables, mais manuellement et désireux - voir reduce:

from operator import or_ 
from functools import reduce 

reduce(or_, [True, False, True]) 
# returns True 
+2

'any()' n'est pas paresseux, il court juste. Sa paresse dépendra de l'itérable que vous lui avez passé comme argument. –

+2

Oui, vous avez raison. Je veux dire "tout" est "paresseux" en termes de "évaluation paresseuse du générateur" et "évaluation booléenne rapide" - s'arrête au premier élément "vrai" - il ne itére pas jusqu'à la fin. –

+1

Vrai, mais le terme correct pour cela est court-circuit. La paresse est quelque chose que vous associeriez à des générateurs, par exemple, ils peuvent interrompre leur exécution et vous retourner le résultat à la demande, pas tous à la fois. Ici 'any()' n'a aucune idée de l'objet qui lui est passé, il l'itére juste un par un. Par conséquent, cela dépend complètement de l'iterable qui lui est passé. –

0

Il y a deux interprétations possibles de la question:

1. OU & et des opérations pour tous les éléments d'un itérables :

OU:any

ET:all

l1 = [True, False, False, True] 
t1 = (True, True, True) 
t2 = (False, False, False, False) 

any(l1) # True 
all(l1) # False 
any(t1) # True 
all(t1) # True 
any(t2) # False 
all(t2) # False 

2.OU & et des opérations pour plusieurs paires donnés en deux iterables:

Dans ce cas, les fonctions utilisées sont les mêmes, mais vous devez utiliser la carte et la fonction zip pour les envelopper:

l = [True, True, False] 
t = (True, False, False) 

list(map(any, zip(l, t))) # [True, True, False] 
tuple(map(all, zip(l, t))) # (True, False, False) 

REMARQUE: J'ai utilisé des listes et des tuples pour prouver que cela peut être fait avec différentes structures de type tableau. Le wrapper de liste et de tuple dans le second exemple est Python3 car la carte renvoie un itérateur au lieu d'une liste et cela donnerait une réponse non lisible par un humain.

0

À partir de votre comment:

dire que j'ai une liste de [0, -1], il doit retourner -1. si [0,0, -1], il doit retourner -1

Alors que la plupart suggèrent d'utiliser any et all, cela ne semble pas être ce que vous voulez réellement:

>>> lst1 = [0, False, [], -1, ""] 
>>> lst2 = [4, True, "", 0] 
>>> any(lst1) 
True 
>>> all(lst2) 
False 

Au lieu de cela, vous peut utiliser le reduce intégré (ou dans le python 3: functools.reduce) avec une fonction concordant lambda, en appliquant or ou and aux opérandes, pour obtenir la première valeur "truthy" or "falsy" dans la liste:

>>> reduce(lambda a, b: a or b, lst1) 
-1 
>>> reduce(lambda a, b: a and b, lst2) 
'' 

En outre, operator.or_ et and_ ne fonctionnera pas, car ceux-ci sont | et & au niveau du bit au lieu de logique or et and.

>>> reduce(operator.or_, lst1) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unsupported operand type(s) for |: 'int' and 'list' 
>>> lst = [1, 2, 4] 
>>> reduce(operator.or_, lst) 
7