Wie überprüfe ich, ob alle Elemente in der Liste Keine sind?

74
In [27]: map( lambda f,p: f.match(p), list(patterns.itervalues()), vatids )
Out[27]: [None, <_sre.SRE_Match object at 0xb73bfdb0>, None]

Die Liste kann ganz Noneoder teilweise eine re.Match-Instanz sein. Welchen Liner-Check kann ich auf der zurückgegebenen Liste durchführen, um mir mitzuteilen, dass alle Inhalte vorhanden sind None?

Frankie Ribéry
quelle
3
Mögliches Duplikat der
Checkliste

Antworten:

170
all(v is None for v in l)

wird zurückgegeben, Truewenn alle Elemente von lsindNone

Beachten Sie, dass dies l.count(None) == len(l)viel schneller ist, aber erfordert, dass es sich lum eine tatsächliche listund nicht nur eine iterierbare handelt.

Dan D.
quelle
Für die Faulen: Hier ist ein Link zu den Dokumenten.
Matt3o12
Wenn der erste Ausdruck einen Generator verwendet, hört er beim ersten NoneAuftreten auf? Warum ist der zweite Ausdruck auch schneller? Mach für mich keinen Sinn.
Suppeault
3
@ s0upa1t allstoppt, wenn das erste falsche Objekt gefunden wird. Die zweite ist zumindest unter CPython schneller, da die Methode .countfür die Objekte des listTyps in C integriert und geschrieben ist und im Gegensatz zum Generator kein Interpreter in die Schleife über die Liste eingebunden ist.
Dan D.
Die Abordnung von Dan D. as all(v is None for v in l)wird true zurückgeben, wenn Sie 0anstelle vonNone
virtualxtc
47
not any(my_list)

Gibt zurück, Truewenn alle Elemente von my_listfalsch sind.

Bearbeiten : Da Übereinstimmungsobjekte immer wahr und Nonefalsch sind, ergibt dies das gleiche Ergebnis wie all(x is None for x in my_list)für den vorliegenden Fall. Wie in der Antwortany() von Gnibbler gezeigt , ist die Verwendung bei weitem die schnellere Alternative.

Sven Marnach
quelle
7
Dieser schlägt für numerische Werte unter 1 fehl, die als falsch gelten
Hund frisst Katzenwelt
5
@Dog: Dein Kommentar ist für diese Frage völlig irrelevant. Übereinstimmungsobjekte bewerten zu True, Nonebewerten zu False. Darüber hinaus wird nur 0 als falsch angesehen, nicht "numerische Werte kleiner als 1".
Sven Marnach
1
@Sven, wie ist mein Kommentar für die Frage irrelevant? Er fragte nach einer Funktion, die erkennen kann, ob eine Liste nur keine Werte enthält. Ihr Beispiel würde [0, Keine] genauso behandeln wie eine Liste mit [Keine, Keine]. Ich sehe mich bei negativen Zahlen falsch, ich bin mir nicht sicher, woher ich das habe!
Hund essen Katzenwelt
2
@Dog: Die Frage erklärt deutlich, dass die Liste aus Rückgabewerten besteht, von re.match()denen entweder Noneoder ein Übereinstimmungsobjekt sind, sodass es einfach keine Rolle spielt, dass diese Lösung fehlschlagen würde 0. Ich habe einige Erklärungen hinzugefügt, um dies klarer zu machen.
Sven Marnach
2
@sleepycal: Ich versuche im Allgemeinen, Antworten zu geben, die die Probleme der Menschen lösen, anstatt genau zu antworten, was sie für ihr Problem halten ("XY-Problem"). Die Frage macht das eigentliche Problem ziemlich klar (stellen Sie fest, ob keines der Muster in der Liste übereinstimmt), und meine Antwort ist eine präzise und schnelle Lösung für dieses Problem.
Sven Marnach
15

Da Match-Objekte niemals als falsch ausgewertet werden, ist es in Ordnung und viel schneller, sie nur zu verwenden not any(L)

$ python -m timeit -s"L=[None,None,None]" "all( v is None for v in L )"
100000 loops, best of 3: 1.52 usec per loop
$ python -m timeit -s"L=[None,None,None]" "not any(L)"
1000000 loops, best of 3: 0.281 usec per loop

$ python -m timeit -s"L=[None,1,None]" "all( v is None for v in L )"
100000 loops, best of 3: 1.81 usec per loop
$ python -m timeit -s"L=[None,1,None]" "not any(L)"
1000000 loops, best of 3: 0.272 usec per loop
John La Rooy
quelle
6

Oder ein bisschen komisch, aber:

a = [None, None, None]
set(a) == set([None])

ODER:

if [x for x in a if x]: # non empty list
    #do something   

EDITIERT:

def is_empty(lVals):
    if not lVals:
        return True
    for x in lVals:
        if x:
            return False
    return True
Artsiom Rudzenka
quelle
2
Beide müssen die gesamte Liste durchlaufen, auch wenn das erste Element nicht None ist.
John La Rooy
@gnibbler - ja, Sie haben Recht, fügte eine weitere "hässliche" Lösung hinzu, die nicht alle Elemente
durchlaufen
Eine prägnantere Definition von is_empty(my_list)wäre return not any(my_list). Zumindest sollten Sie die ersten beiden Zeilen weglassen.
Sven Marnach
@Sven - ja - Sie haben Recht und versuchen einfach, keine andere Lösung zu duplizieren, sondern die gleiche Funktionalität bereitzustellen. Ich weiß, dass es bereits besprochen wurde und die '
All'
0
is_all_none = lambda L: not len(filter(lambda e: not e is None, L))

is_all_none([None,None,'x'])
False
is_all_none([None,None,None])
True
Hund frisst Katzenwelt
quelle
Abgesehen davon, dass es im Vergleich zu den Standardantworten sehr ausführlich ist, verwirrt es mich, warum Sie lambdahier anstelle der einfachen verwenden würden def.
RoundTower
@RoundTower, weil er nach einem Einzeiler gefragt hat. Ich vermutete, dass er es als Inline-Funktion verwenden würde, da er in seinem Beispiel bereits Lambdas verwendet hatte.
Hund essen Katzenwelt
@RoundTower "Leitbleche"? Der Def ist ein paar Zeilen länger, wenn Sie die erforderlichen Leerzeilen für Funktionen einschließen. Ich verstehe nicht, warum Python-Programmierer sich nicht um das Aufblähen der Codelänge kümmern - es ist viel mehr Platz auf dem Bildschirm. Wir sprechen nicht davon, fünfzig Linien zu einem A-la- Perl- Code-Golf zu verdichten, sondern auch nicht davon, eine oder zwei Linien zu 5 oder 10 zu erweitern
StephenBoesch
0

Ich habe es geschafft, einen Ansatz zu finden map, der noch nicht gegeben wurde

tl; dr

def all_none(l):
    return not any(map(None.__ne__, l))

all_none([None, None, None]) # -> True
all_none([None, None, 8])    # -> False

Erläuterung

Die Verwendung von None.__ne__ist etwas seltsamer als man auf den ersten Blick erwarten würde. Diese Methode gibt ein NotImplementedTypeObjekt zurück, wenn etwas angegeben wird, das nicht None ist.

Sie würden hoffen, dass NotImplementeddies ein FalseErsatz sein würde , aber es ist auch wahr! Dies bedeutet, dass die Verwendung None.__eq__in einer Sammlung für alles Thruthy-Werte erzeugt.

list(map(None.__eq__, [None, None, 8]))
# -> [True, True, NotImplemented]

all(list(map(None.__eq__, [None, None, 8])))
# -> True

Aus den Python-Dokumenten :

Standardmäßig wird ein Objekt als wahr betrachtet, es sei denn, seine Klasse definiert entweder eine bool () -Methode, die False zurückgibt, oder eine len () -Methode, die Null zurückgibt

Stattdessen None.__ne__gibt Falsefür alle NoneElemente, und ein NotImplementedTypeObjekt für etwas anderes:

list(map(None.__ne__, [None, None, 8]))
# -> [False, False, NotImplemented]

Mit diesem können Sie überprüfen , ob anyElemente nicht , Nonedie angezeigt werden können True. Ich stelle mir das gerne als zwei getrennte Methoden vor, wenn das bei der mentalen Negationsgymnastik hilft.

def contains_truthy(l):
    return any(map(None.__ne__, l))

def all_none(l):
    return not contains_truthy(l)

Ich habe damit kein Benchmarking durchgeführt, aber wie von anderen in diesem Thread erwähnt, not anywerden schnelle Ergebnisse erzielt.

tmck-code
quelle