Überprüfen Sie, ob alle Werte in der Liste größer als eine bestimmte Zahl sind

81
my_list1 = [30,34,56]
my_list2 = [29,500,43]

Wie überprüfe ich, ob alle Werte in der Liste> = 30 sind? my_list1sollte funktionieren und my_list2sollte nicht.

Das einzige, woran ich denken konnte, war:

boolean = 0
def func(ls):
    for k in ls:
        if k >= 30:
            boolean = boolean + 1
        else:
            boolean = 0
    if boolean > 0:
        print 'Continue'
    elif boolean = 0:
        pass

Update 2016:

Im Nachhinein numpywürde ich Folgendes tun , nachdem ich mich mit größeren Datensätzen befasst habe, bei denen Geschwindigkeit tatsächlich wichtig ist, und ...

>>> my_list1 = [30,34,56]
>>> my_list2 = [29,500,43]

>>> import numpy as np
>>> A_1 = np.array(my_list1)
>>> A_2 = np.array(my_list2)

>>> A_1 >= 30
array([ True,  True,  True], dtype=bool)
>>> A_2 >= 30
array([False,  True,  True], dtype=bool)

>>> ((A_1 >= 30).sum() == A_1.size).astype(np.int)
1
>>> ((A_2 >= 30).sum() == A_2.size).astype(np.int)
0

Sie könnten auch so etwas tun:

len([*filter(lambda x: x >= 30, my_list1)]) > 0
O.rka
quelle
Ein allgemeines Problem, das Sie beachten sollten: 1) Die zugewiesene booleanVariable ist lokal für die Funktion (da keine entsprechende globalAnmerkung vorhanden ist ) und 2) boolean = 0ist eine Zuweisung , kein Vergleich.
user2864740
Beachten Sie, dass Sie my_list1hat einen Wert, der ist nicht über 30 , dass es stattdessen gleich 30 Should 31 statt sein, oder testen Sie für mehr als oder gleich 30 hier?
Martijn Pieters

Antworten:

140

Verwenden Sie die all()Funktion mit einem Generatorausdruck:

>>> my_list1 = [30, 34, 56]
>>> my_list2 = [29, 500, 43]
>>> all(i >= 30 for i in my_list1)
True
>>> all(i >= 30 for i in my_list2)
False

Beachten Sie, dass dieser Test größer oder gleich 30 ist, andernfalls my_list1würde der Test auch nicht bestanden.

Wenn Sie dies in einer Funktion tun möchten, verwenden Sie:

def all_30_or_up(ls):
    for i in ls:
        if i < 30:
            return False
    return True

Sobald Sie beispielsweise einen Wert finden, der beweist, dass ein Wert unter 30 liegt, kehren Sie zurück Falseund kehren zurück, Truewenn Sie keine gegenteiligen Beweise gefunden haben.

Ebenso können Sie mit der any()Funktion testen, ob mindestens 1 Wert der Bedingung entspricht.

Martijn Pieters
quelle
Was ist der Vorteil von all_30_or_upüber all? Sollte nicht allauch aufhören, den Iterator zu verbrauchen, sobald ein Negativ gefunden wurde? Wäre sonst ziemlich dumm, nicht wahr?
Hyperboreus
1
@Hyperboreus: Beide hören auf, sobald ein Negativ gefunden wurde. Ich wollte dem OP eine andere Sichtweise auf das Problem geben und ihnen eine Funktion geben, die die von ihnen geschriebene ersetzt.
Martijn Pieters
@ MartinijnPieters, Mucho <3
zelusp
9

... einen Grund, warum Sie nicht verwenden können min()?

def above(my_list, minimum):
    if min(my_list) >= minimum:
        print "All values are equal or above", minimum
    else:
        print "Not all values are equal or above", minimum

Ich weiß nicht, ob das genau das ist, was Sie wollen, aber technisch gesehen haben Sie darum gebeten ...

Roberto
quelle
2
Der Nachteil dieser Lösung ist, dass jedes Listenelement berührt werden muss.
Hyperboreus
2
Ich habe ein wenig Profiling dazu gemacht. allKurzschlüsse, daher ist es viel schneller, wenn die Liste nicht qualifiziert ist. Aber wenn die Liste alle 30+ ist, minkann schneller sein. Ich habe mit zwei 1000-Element-Listen zufälliger Ganzzahlen getestet, eine mit random.randint(0, 100)(fehlgeschlagen) und eine mit random.randint(30, 100). Die Verwendung minauf der 30-100-Liste dauerte etwas weniger als die Hälfte der Zeit. Es alldauerte jedoch ungefähr 2% der Zeit, mindie auf der 0-100-Liste verstrichen ist, sodass es wahrscheinlich gewinnt, es sei denn, fehlerhafte Listen sind sehr selten.
Peter DeGlopper
1
Wie sich herausstellte, lag das erste Element meiner 0-100-Liste unter 30, so dass mein Test irgendwie entartet war. Das erste Element unter 30 zu minerzwingen , das sich in der Mitte der Liste befindet, wird etwas schneller ausgeführt - 0,25 s für 10000 Wiederholungen anstelle von 0,32 s für all. Was also schneller ist, hängt erwartungsgemäß von der Art der Daten ab.
Peter DeGlopper
4

Es gibt eine eingebaute Funktion all:

all (x > limit for x in my_list)

Begrenzen Sie den Wert, der größer ist als alle Zahlen.

Hyperboreus
quelle
Wie my_list1sollte testen True, sollte der Test mit ziemlicher Sicherheit >= 30nicht sein > 30.
Martijn Pieters
1
Nun, wenn sich der Fragetext von OP widerspricht, wer bin ich, um zu beurteilen, welches die richtige Grenze ist?
Hyperboreus
3

Sie können verwenden all():

my_list1 = [30,34,56]
my_list2 = [29,500,43]
if all(i >= 30 for i in my_list1):
    print 'yes'
if all(i >= 30 for i in my_list2):
    print 'no'

Beachten Sie, dass dies alle Zahlen umfasst, die gleich 30 oder höher sind und nicht unbedingt über 30 liegen.

Simeon Visser
quelle
Wie my_list1sollte testen True, sollte der Test mit ziemlicher Sicherheit >= 30nicht sein > 30.
Martijn Pieters
@ MartinijnPieters danke, jetzt aktualisiert. Frage erwähnt über 30, >= 30scheint aber beabsichtigt.
Simeon Visser
Ich weiß, deshalb habe ich das explizit gemacht. :-)
Martijn Pieters
2

Der Gesamtsieger zwischen der Verwendung von np.sum, np.min und all scheint in Bezug auf die Geschwindigkeit für große Arrays np.min zu sein:

N = 1000000
def func_sum(x):
    my_list = np.random.randn(N)
    return np.sum(my_list < x )==0

def func_min(x):
    my_list = np.random.randn(N)
    return np.min(my_list) >= x

def func_all(x):
    my_list = np.random.randn(N)
    return all(i >= x for i in my_list)

(Ich muss die Definition von np.array in die Funktion einfügen, andernfalls merkt sich die Funktion np.min den Wert und führt die Berechnung nicht erneut durch, wenn die Geschwindigkeit mit der Zeit getestet wird.)

Die Leistung von "all" hängt sehr davon ab, wann das erste Element gefunden wird, das die Kriterien nicht erfüllt. Die np.sum muss einige Operationen ausführen. Die np.min ist im allgemeinen Fall die leichteste in Bezug auf Berechnungen .

Wenn die Kriterien fast sofort erfüllt sind und die All-Schleife schnell beendet wird, gewinnt die All-Funktion nur geringfügig über np.min:

>>> %timeit func_sum(10)
10 loops, best of 3: 36.1 ms per loop

>>> %timeit func_min(10)
10 loops, best of 3: 35.1 ms per loop

>>> %timeit func_all(10)
10 loops, best of 3: 35 ms per loop

Aber wenn "alle" alle Punkte durchgehen müssen, ist es definitiv viel schlimmer und die np.min gewinnt:

>>> %timeit func_sum(-10)
10 loops, best of 3: 36.2 ms per loop

>>> %timeit func_min(-10)
10 loops, best of 3: 35.2 ms per loop

>>> %timeit func_all(-10)
10 loops, best of 3: 230 ms per loop

Aber mit

np.sum(my_list<x)

kann sehr nützlich sein, wenn man wissen möchte, wie viele Werte unter x liegen.

Chachni
quelle
0

Sie können Folgendes tun:

def Lists():

    my_list1 = [30,34,56]
    my_list2 = [29,500,43]

    for element in my_list1:
        print(element >= 30)

    for element in my_list2:
        print(element >= 30)

Lists()

Dadurch werden die Werte, die größer als 30 sind, als True und die Werte, die kleiner als false sind, zurückgegeben.

Filip Grebowski
quelle
0

Ich schreibe diese Funktion

def larger(x, than=0):
    if not x or min(x) > than:
        return True
    return False

Dann

print larger([5, 6, 7], than=5)  # False
print larger([6, 7, 8], than=5)  # True
print larger([], than=5)  # True
print larger([6, 7, 8, None], than=5)  # False


Eine leere Liste auf min () löst ValueError aus. Also habe ich if not xin Zustand hinzugefügt .

Shameem
quelle