Verifique si todos los valores en la lista son mayores que un cierto número

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

¿Cómo verifico si todos los valores en la lista son> = 30? my_list1debería funcionar y my_list2no debería.

Lo único que se me ocurrió hacer fue:

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

Actualización 2016:

En retrospectiva, después de tratar con conjuntos de datos más grandes donde la velocidad realmente importa y utilizar numpy... haría esto:

>>> 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

También puedes hacer algo como:

len([*filter(lambda x: x >= 30, my_list1)]) > 0
O.rka
fuente
Aspectos generales a tener en cuenta: 1) la booleanvariable asignada es local a la función (ya que no hay una globalanotación apropiada ), y 2) boolean = 0es una asignación , no una comparación.
user2864740
Tenga en cuenta que su my_list1tiene un valor que no está por encima de 30. En cambio, es igual a 30. ¿Debería ser 31 en su lugar, o está probando un valor mayor o igual a 30 aquí?
Martijn Pieters

Respuestas:

140

Usa la all()función con una expresión generadora:

>>> 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

Tenga en cuenta que esta prueba para valores mayores o iguales a 30, de lo contrario my_list1tampoco pasaría la prueba.

Si quisiera hacer esto en una función, usaría:

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

Por ejemplo, tan pronto como encuentre un valor que pruebe que hay un valor por debajo de 30, regresa Falsey regresa Truesi no encontró evidencia en contrario.

De manera similar, puede usar la any()función para probar si al menos 1 valor coincide con la condición.

Martijn Pieters
fuente
¿Cuál es la ventaja de usar all_30_or_upover all? ¿No debería alldejar de consumir el iterador tan pronto como se encuentre un negativo? Sería bastante tonto de lo contrario, ¿no?
Hyperboreus
1
@Hyperboreus: ambos se detienen tan pronto como se encuentra un negativo. Quería darle al OP una forma diferente de ver el problema, dándoles una función para reemplazar la que estaban escribiendo.
Martijn Pieters
@MartijnPieters, Mucho <3
zelusp
9

... ¿alguna razón por la que no puedas usar 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

No sé si esto es exactamente lo que quieres, pero técnicamente, esto es lo que pediste ...

Roberto
fuente
2
La desventaja de esta solución es que se debe tocar cada elemento de la lista.
Hyperboreus
2
Hice un pequeño perfil sobre esto. allcortocircuitos, por lo que es mucho más rápido si la lista no califica. Pero si la lista es de más de 30, minpuede ser más rápido. Probé con dos listas de 1000 elementos de enteros aleatorios, una llena con random.randint(0, 100)(fallando) y otra llena con random.randint(30, 100). El uso mintomó un poco menos de la mitad del tiempo en la lista 30-100. Pero alltomó alrededor del 2% del tiempo que lo minhizo en la lista 0-100, por lo que probablemente gane a menos que las listas fallidas sean muy raras.
Peter DeGlopper
1
Al final resultó que, el primer elemento de mi lista 0-100 estaba por debajo de 30, por lo que mi prueba fue un poco degenerada. Forzar que el primer elemento sub-30 esté en la mitad de la lista, minsale un poco más rápido: 0.25s para 10000 repeticiones en lugar de 0.32s para all. Entonces, cuál es más rápido depende de la naturaleza de los datos, como era de esperar.
Peter DeGlopper
4

Hay una función incorporada all:

all (x > limit for x in my_list)

Siendo límite el valor mayor al que deben ser todos los números.

Hiperbóreo
fuente
Como my_list1debería ser la prueba True, es casi seguro que la prueba debería ser >= 30, no > 30.
Martijn Pieters
1
Bueno, cuando el texto de la pregunta de OP se contradice, ¿quién soy yo para juzgar cuál es el límite correcto?
Hyperboreus
3

Puede utilizar 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'

Tenga en cuenta que esto incluye todos los números iguales a 30 o superiores, no estrictamente superiores a 30.

Simeon Visser
fuente
Como my_list1debería ser la prueba True, es casi seguro que la prueba debería ser >= 30, no > 30.
Martijn Pieters
@MartijnPieters gracias, ahora actualizado. La pregunta menciona más de 30 pero >= 30parece intencionada.
Simeon Visser
Lo sé, por eso lo hice explícito. :-)
Martijn Pieters
2

El ganador general entre el uso de np.sum, np.min y todo parece ser np.min en términos de velocidad para matrices grandes:

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)

(Necesito poner la definición np.array dentro de la función; de lo contrario, la función np.min recuerda el valor y no vuelve a realizar el cálculo cuando se prueba la velocidad con timeit)

El rendimiento de "all" depende mucho de cuándo se encuentra el primer elemento que no satisface los criterios, el np.sum necesita hacer un poco de operaciones, el np.min es el más ligero en términos de cálculos en el caso general .

Cuando los criterios se cumplen casi de inmediato y el bucle todo sale rápido, la función all gana solo un poco sobre 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

Pero cuando "todos" deben pasar por todos los puntos, definitivamente es mucho peor, y el np.min gana:

>>> %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

Pero usando

np.sum(my_list<x)

puede ser muy útil si uno quiere saber cuántos valores están por debajo de x.

Chachni
fuente
0

Puedes hacer lo siguiente:

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()

Esto devolverá los valores mayores que 30 como Verdadero y los valores menores como falso.

Filip Grebowski
fuente
0

Escribo esta función

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

Entonces

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


La lista vacía en min () generará ValueError. Así que agregué if not xen condición.

Vergüenza
fuente