it-swarm.com.de

Wie überprüfe ich, ob alle Elemente einer Liste einer Bedingung entsprechen?

Ich habe eine Liste bestehend aus 20000 Listen. Ich benutze das 3. Element jeder Liste als Flag. Ich möchte einige Operationen an dieser Liste ausführen, solange mindestens das Flag eines Elements 0 ist.

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

Am Anfang sind alle Flags 0. Ich benutze eine while-Schleife, um zu überprüfen, ob das Flag eines Elements 0 ist:

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

Wenn check(my_list)True zurückgibt, arbeite ich weiter an meiner Liste:

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

Eigentlich wollte ich ein Element in my_list entfernen, während ich darüber iterierte, aber ich darf keine Elemente entfernen, während ich darüber iteriere.

Ursprüngliche my_list hatte keine Flags:

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

Da ich beim Durchlaufen keine Elemente entfernen konnte, habe ich diese Flags erfunden. Aber der my_list Enthält viele Elemente, und die while -Schleife liest sie alle bei jeder for -Schleife und verbraucht viel Zeit! Hast du irgendwelche Vorschläge?

178
alwbtc

Die beste Antwort ist hier all() , das für diese Situation eingebaut ist. Wir kombinieren dies mit einem Generatorausdruck , um das gewünschte Ergebnis sauber und effizient zu erzielen. Zum Beispiel:

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

Und für sein Filterbeispiel ein Listenverständnis:

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

Wenn Sie überprüfen möchten, ob mindestens ein Element 0 ist, ist die bessere Option die Verwendung von any() , die besser lesbar ist:

>>> any(item[2] == 0 for item in items)
True
345
Gareth Latty

Sie können das takewhile von itertools wie folgt verwenden. Es wird beendet, sobald eine Bedingung erfüllt ist, die Ihre Aussage nicht erfüllt. Die gegenteilige Methode wäre in absehbarer Zeit

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

Wenn Sie überprüfen möchten, ob ein Element in der Liste eine Bedingung verletzt, verwenden Sie all:

if all([x[2] == 0 for x in lista]):
    # Will run if all elements in the list has x[2] = 0 (use not to invert if necessary)

Verwenden Sie filter, um alle nicht übereinstimmenden Elemente zu entfernen.

# Will remove all elements where x[2] is 0
listb = filter(lambda x: x[2] != 0, listb)
6
Hampus Nilsson

diese Methode ist etwas flexibler als die Verwendung von 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

oder prägnanter:

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

Eine andere Möglichkeit, itertools.ifilter. Dies überprüft die Richtigkeit und den Prozess (mit lambda)

Stichprobe-

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