318 votes

Comment vérifier si tous les éléments d'une liste correspondent à une condition?

Je dispose d'une liste qui contient de nombreuses sous-listes de 3 éléments chacune, comme suit :

my_list = [["a", "b", 0], ["c", "d", 0], ["e", "f", 0], .....]

Le dernier élément de chaque sous-liste est une sorte de drapeau, qui est initialement à 0 pour chaque sous-liste. Au fur et à mesure que mon algorithme progresse, je veux vérifier si ce drapeau est à 0 pour au moins un élément. Actuellement, j'utilise une boucle while, comme ceci :

def check(list_):
    for item in list_:
        if item[2] == 0:
            return True
    return False

L'algorithme global boucle tant que cette condition est satisfaite, et définit certains des drapeaux à chaque itération :

while check(my_list):
    for item in my_list:
        if condition:
            item[2] = 1
        else:
            do_sth()

Parce que cela pose des problèmes de supprimer des éléments de la liste tout en itérant dessus, j'utilise ces drapeaux pour suivre les éléments qui ont déjà été traités.

Comment puis-je simplifier ou accélérer le code ?


Voir aussi <a href="https://stackoverflow.com/questions/1342601/">Manière pythonique de vérifier si une condition est vraie pour n'importe quel élément d'une liste</a> pour vérifier la condition pour n'importe quel élément. Gardez à l'esprit que les vérifications "any" et "all" sont liées <a href="https://stackoverflow.com/questions/2168603/">par la loi de De Morgan</a>, tout comme "or" et "and" sont liés.

Les réponses existantes utilisent la fonction intégrée <code>all</code> pour faire l'itération. Consultez <a href="https://stackoverflow.com/questions/19389490">Comment fonctionnent les fonctions any et all de Python ?</a> pour une explication de <code>all</code> et de son homologue, <code>any</code>.

Si la condition que vous souhaitez vérifier est "est trouvée dans un autre conteneur", consultez <a href="https://stackoverflow.com/questions/3931541/">Comment vérifier si tous les éléments suivants sont dans une liste ?</a> et son homologue, <a href="https://stackoverflow.com/questions/740287">Comment vérifier si l'un des éléments suivants est dans une liste ?</a>. Utiliser <code>any</code> et <code>all</code> fonctionnera, mais des solutions plus efficaces sont possibles.

552voto

Lattyware Points 37257

La meilleure réponse ici est d'utiliser all(), qui est l'instruction intégrée pour cette situation. Nous combinons cela avec une expression de générateur pour produire le résultat que vous voulez proprement et efficacement. Par exemple :

>>> items = [[1, 2, 0], [1, 2, 0], [1, 2, 0]]
>>> all(flag == 0 for (_, _, flag) in items)
True
>>> items = [[1, 2, 0], [1, 2, 1], [1, 2, 0]]
>>> all(flag == 0 for (_, _, flag) in items)
False

Notez que all(flag == 0 for (_, _, flag) in items) est directement équivalent à all(item[2] == 0 for item in items), c'est juste un peu plus agréable à lire dans ce cas.

Et, pour l'exemple de filtre, une compréhension de liste (bien sûr, vous pourriez utiliser une expression de générateur si approprié) :

>>> [x for x in items if x[2] == 0]
[[1, 2, 0], [1, 2, 0]]

Si vous voulez vérifier qu'au moins un élément est égal à 0, la meilleure option est d'utiliser any() qui est plus lisible :

>>> any(flag == 0 for (_, _, flag) in items)
True

31voto

Hampus Nilsson Points 4154

Si vous voulez vérifier si un élément de la liste viole une condition, utilisez all:

if all([x[2] == 0 for x in lista]):
    # S'exécutera si tous les éléments de la liste ont x[2] = 0 (utilisez not pour inverser si nécessaire)

Pour supprimer tous les éléments qui ne correspondent pas, utilisez filter

# Supprimera tous les éléments où x[2] est égal à 0
listb = filter(lambda x: x[2] != 0, listb)

8voto

Vous pourriez utiliser takewhile d'itertools comme ceci, il s'arrêtera une fois qu'une condition est rencontrée qui ne respecte pas votre déclaration. La méthode opposée serait dropwhile

for x in itertools.takewhile(lambda x: x[2] == 0, liste)
    print x

1voto

mulllhausen Points 610

Cette manière est un peu plus flexible que d'utiliser all():

my_list = [[1, 2, 0], [1, 2, 0], [1, 2, 0]]
all_zeros = False if False in [x[2] == 0 for x in my_list] else True
any_zeros = True if True in [x[2] == 0 for x in my_list] else False

ou de manière plus succincte:

all_zeros = not False in [x[2] == 0 for x in my_list]
any_zeros = 0 in [x[2] for x in my_list]

0voto

SIslam Points 4075

Un autre moyen d'utiliser itertools.ifilter. Cela vérifie la véracité et le processus (utilisant lambda)

Exemple-

for x in itertools.ifilter(lambda x: x[2] == 0, my_list):
    print x

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X