Перевірте, чи всі значення у списку перевищують певне число


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

Як перевірити, чи всі значення у списку> 30? my_list1повинні працювати іmy_list2 не повинен.

Єдине, що я міг подумати:

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

Оновлення 2016:

Оглянувшись назад, після роботи з більшими наборами даних, де швидкість насправді має значення та використання numpy... Я б зробив це:

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

Ви також можете зробити щось на зразок:

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

Загальні проблеми, про які слід пам’ятати: 1) призначена booleanзмінна є локальною для функції (оскільки немає відповідної globalанотації ), та 2) boolean = 0є призначенням , а не порівнянням.
user2864740

Зверніть увагу, що у вас my_list1є одне значення, яке не перевищує 30. Натомість воно дорівнює 30. Чи має це бути замість цього 31, чи ви тут тестуєте більше або дорівнює 30?
Мартін Пітерс

Відповіді:


146

Використовуйте all()функцію з виразом генератора:

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

Зверніть увагу, що ці тести більше або дорівнюють 30, інакше my_list1тест також не пройшов би.

Якщо ви хочете зробити це у функції, ви б використали:

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

наприклад , як тільки ви знайшли значення , яке доводить , що існує значення нижче 30, ви повернетеся , і повернення , якщо ви не знайшли ніяких доказів зворотного.FalseTrue

Аналогічним чином ви можете використовувати any()функцію для перевірки, чи принаймні 1 значення відповідає умові.


Яка перевага використання all_30_or_upнад all? Чи не слід allтакож припинити споживання ітератора, як тільки буде знайдено негатив? Інакше було б зовсім німо, правда?
Гіперборей

1
@Hyperboreus: обидва зупиняються, як тільки виявляється негатив. Я хотів дати ОП інший спосіб розглянути проблему, надавши їм функцію, яка замінить ту, яку вони писали.
Мартін Пітерс

@MartijnPieters, Mucho <3
zelusp

9

... будь-яка причина, чому ви не можете використовувати 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

Я не знаю, чи це саме те, що ти хочеш, але технічно це те, про що ти просив ...


2
Недоліком цього рішення є те, що кожен пункт списку повинен бути торкнутий.
Гіперборей

2
Я зробив трохи профілювання з цього приводу. allкороткі замикання, тому це набагато швидше, якщо список не відповідає вимогам. Але якщо в списку більше 30+, minможе бути і швидше. Я протестував із двома списками випадкових цілих чисел з 1000 елементів, одним заповненим random.randint(0, 100)(невдалим) та іншим заповненим random.randint(30, 100). Використання minзайняло трохи менше половини часу у списку 30-100. Але це allзайняло близько 2% часу, яке minбуло у списку 0-100, тому він, ймовірно, виграє, якщо невдалі списки є дуже рідкісними.
Пітер ДеГлоппер

1
Як виявилося, перший елемент мого списку 0-100 був нижче 30, тому мій тест був дещо виродженим. Змушуючи перший елемент під 30 пройти половину списку, це minвиходить трохи швидше - 0,25 с для 10000 повторень, а не 0,32 с для all. Отже, що швидше, залежить від природи даних, як і слід було очікувати.
Пітер ДеГлоппер

4

Існує вбудована функція all :

all (x > limit for x in my_list)

Будучи обмеженим значенням, більшим за яке повинні бути всі числа.


Як my_list1слід перевірити True, тест майже напевно повинен бути >= 30, а не > 30.
Мартін Пітерс

1
Ну, коли текст запитання OP суперечить сам собі, хто я такий, щоб судити, яка правильна межа.
Гіперборей

3

Ви можете використовувати 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'

Зверніть увагу, що сюди входять усі числа, що дорівнюють 30 або вище, а не строго вище 30.


Як my_list1слід перевірити True, тест майже напевно повинен бути >= 30, а не > 30.
Мартін Пітерс

@MartijnPieters дякую, зараз оновлено. Питання згадує понад 30, але, >= 30здається, призначений.
Симеон Віссер

Я знаю, тому я це чітко заявив. :-)
Мартін Пітерс

2

Загальним переможцем між використанням np.sum, np.min і всім, здається, є np.min з точки зору швидкості для великих масивів:

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)

(мені потрібно помістити визначення np.array всередину функції, інакше функція np.min запам'ятовує значення і не робить обчислення знову при тестуванні швидкості з timeit)

Виконання "всіх" дуже сильно залежить від того, коли буде знайдено перший елемент, який не відповідає критеріям, np.sum потрібно виконати трохи операцій, np.min - найлегший з точки зору обчислень у загальному випадку .

Коли критерії майже відразу виконуються, і весь цикл швидко виходить, функція all виграє трохи більше, ніж 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

Але коли "всім" потрібно пройти всі пункти, це, безумовно, набагато гірше, і np.min виграє:

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

Але використовуючи

np.sum(my_list<x)

може бути дуже корисним, якщо хочеться знати, скільки значень нижче x.


0

Ви можете зробити наступне:

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

Це поверне значення, які перевищують 30, як True, а значення, які є меншими, як false.


0

Я пишу цю функцію

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

Тоді

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


Порожній список на min () призведе до ValueError. Тож я додав if not xу стані.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.