Sprawdź, czy wszystkie wartości na liście są większe niż określona liczba


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

Jak sprawdzić, czy wszystkie wartości na liście są> = 30? my_list1powinien działać, a my_list2nie powinien.

Jedyne, o czym przyszło mi do głowy, to:

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

Aktualizacja 2016:

Z perspektywy czasu, po poradzeniu sobie z większymi zbiorami danych, w których prędkość naprawdę ma znaczenie i wykorzystaniu numpy... zrobiłbym to:

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

Możesz też zrobić coś takiego:

len([*filter(lambda x: x >= 30, my_list1)]) > 0

Ogólne kwestie, o których należy pamiętać: 1) przypisana booleanzmienna jest lokalna dla funkcji (ponieważ nie ma odpowiedniej globaladnotacji ), oraz 2) boolean = 0jest przypisaniem , a nie porównaniem.
— user2864740

Zauważ, że twoja my_list1ma jedną wartość, która nie jest większa niż 30. Zamiast tego jest równa 30. Czy zamiast tego powinno być 31, czy też testujesz tutaj dla większej lub równej 30?
— Martijn Pieters

Odpowiedzi:


147

Użyj all()funkcji z wyrażeniem generatora:

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

Zauważ, że te testy dla większej lub równej 30, w przeciwnym razie my_list1również nie przejdą testu.

Gdybyś chciał to zrobić w funkcji, użyłbyś:

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

np jak najszybciej znaleźć wartość, która udowadnia, że istnieje wartość poniżej 30, powrót i zwrot , jeśli nie znaleziono dowodów przeciwnych.FalseTrue

Podobnie możesz użyć any()funkcji do sprawdzenia, czy co najmniej 1 wartość pasuje do warunku.


Jaka jest zaleta używania all_30_or_upnad all? Czy nie należy allrównież zaprzestać używania iteratora, gdy tylko zostanie znaleziony negatyw? Byłoby całkiem głupie, prawda?
— Hyperboreus

1
@Hyperboreus: oba kończą się, gdy tylko zostanie znaleziony negatyw. Chciałem dać OP inny sposób patrzenia na problem, dając im funkcję zastępującą tę, którą pisali.
— Martijn Pieters

@MartijnPieters, Mucho <3
— zelusp

9

... jest jakiś powód, dla którego nie możesz użyć 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

Nie wiem, czy dokładnie tego chcesz, ale technicznie rzecz biorąc, o to prosiłeś ...


2
Wadą tego rozwiązania jest konieczność dotknięcia każdej pozycji listy.
— Hyperboreus

2
Zrobiłem małe profilowanie na ten temat. allzwarcia, więc jest znacznie szybciej, jeśli lista się nie kwalifikuje. Ale jeśli lista zawiera wszystkie 30+, minmoże być szybsza. Testowałem z dwoma 1000-elementowymi listami losowych liczb całkowitych, jedną wypełnioną random.randint(0, 100)(niepowodzenie) i jedną wypełnioną random.randint(30, 100). Używanie minzajęło nieco mniej niż połowę czasu na liście 30-100. Ale allzajęło to około 2% czasu minna liście 0-100, więc prawdopodobnie wygrywa, chyba że niepowodzenia na listach są bardzo rzadkie.
— Peter DeGlopper

1
Jak się okazało, pierwszy element mojej listy 0-100 był poniżej 30, więc mój test był trochę zdegenerowany. Wymuszenie pierwszego elementu pod-30 na połowie listy minwychodzi nieco szybciej - 0,25 s dla 10000 powtórzeń zamiast 0,32 s dla all. To, co jest szybsze, zależy od charakteru danych, jak można się spodziewać.
— Peter DeGlopper

4

Jest wbudowana funkcja all:

all (x > limit for x in my_list)

Bycie ograniczonym wartością większą niż musi mieć wszystkie liczby.


Jak my_list1powinien test True, test prawie na pewno powinien być >= 30, nie > 30.
— Martijn Pieters

1
Cóż, kiedy tekst pytania OP zaprzecza samemu sobie, kim jestem, aby ocenić, który jest prawidłowy limit.
— Hyperboreus

3

Możesz użyć 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'

Zwróć uwagę, że obejmuje to wszystkie liczby równe 30 lub wyższe, a nie ściśle powyżej 30.


Jak my_list1powinien test True, test prawie na pewno powinien być >= 30, nie > 30.
— Martijn Pieters

@MartijnPieters dzięki, teraz zaktualizowane. Pytanie dotyczy powyżej 30, ale >= 30wydaje się zamierzone.
— Simeon Visser

Wiem, dlatego wyraziłem to wyraźnie. :-)
— Martijn Pieters

2

Ogólny zwycięzca między użyciem np.sum, np.min, a wszystkim wydaje się być np.min pod względem szybkości dla dużych tablic:

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)

(Muszę umieścić definicję np.array wewnątrz funkcji, w przeciwnym razie funkcja np.min zapamiętuje wartość i nie wykonuje ponownie obliczeń podczas testowania prędkości z timeit)

Wydajność "all" zależy w dużej mierze od tego kiedy zostanie znaleziony pierwszy element nie spełniający kryteriów, np.sum musi wykonać trochę operacji, np.min jest najlżejszy pod względem obliczeń w ogólnym przypadku .

Gdy kryteria są prawie natychmiast spełnione i pętla all szybko się kończy, funkcja all wygrywa nieco powyżej 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

Ale gdy "wszystko" musi przejść przez wszystkie punkty, jest zdecydowanie gorzej i np.min wygrywa:

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

Ale używając

np.sum(my_list<x)

może być bardzo przydatne, gdy chce się wiedzieć, ile wartości znajduje się poniżej x.


0

Możesz wykonać następujące czynności:

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

Spowoduje to zwrócenie wartości, które są większe niż 30 jako True, a wartości mniejsze jako false.


0

Piszę tę funkcję

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

Następnie

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


Pusta lista w min () spowoduje zgłoszenie błędu ValueError. Więc dodałem if not xw stanie.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.