Как работают Python все и все функции?

Я пытаюсь понять, как работают встроенные функции any() и all() Python.

Я пытаюсь сравнить кортежи, чтобы, если какое-либо значение отличается, оно возвращает True, и если они все равно, он вернет False. Как они работают в этом случае для возврата [False, False, False]?

d является defaultdict(list).

print d['Drd2']
# [[1, 5, 0], [1, 6, 0]]
print list(zip(*d['Drd2']))
# [(1, 1), (5, 6), (0, 0)]
print [any(x) and not all(x) for x in zip(*d['Drd2'])]
# [False, False, False]

Насколько мне известно, это должно выводить

# [False, True, False]

так как (1,1) совпадают, (5,6) различны и (0,0) совпадают.

Почему он вычисляет False для всех кортежей?

Ответ 1

Вы можете приблизительно думать о any и all как о серии логических операторов or и and, соответственно.

любой

any вернет True, когда по крайней мере один из элементов будет Truthy. Читайте о Проверка достоверности истины.

все

all вернет True только тогда, когда все элементы являются Truthy.

Таблица истинности

+-----------------------------------------+---------+---------+
|                                         |   any   |   all   |
+-----------------------------------------+---------+---------+
| All Truthy values                       |  True   |  True   |
+-----------------------------------------+---------+---------+
| All Falsy values                        |  False  |  False  |
+-----------------------------------------+---------+---------+
| One Truthy value (all others are Falsy) |  True   |  False  |
+-----------------------------------------+---------+---------+
| One Falsy value (all others are Truthy) |  True   |  False  |
+-----------------------------------------+---------+---------+
| Empty Iterable                          |  False  |  True   |
+-----------------------------------------+---------+---------+

Примечание 1: Пустой итерируемый случай объясняется в официальной документации, например,

any

Возвращает True, если любой элемент итерабельности является истинным. Если итерабельность пуста, верните False

Поскольку ни один из элементов не является истинным, он возвращает False в этом случае.

all

Возвращает True, если все элементы итерабельны являются истинными (или если итерабельность пуста).

Поскольку ни один из элементов не является false, он возвращает True в этом случае.


Примечание 2:

Еще одна важная вещь, которую нужно знать о any и all, - это короткое замыкание выполнения, как только они узнают результат. Преимущество состоит в том, что не нужно потреблять целые итерации. Например,

>>> multiples_of_6 = (not (i % 6) for i in range(1, 10))
>>> any(multiples_of_6)
True
>>> list(multiples_of_6)
[False, False, False]

Здесь (not (i % 6) for i in range(1, 10)) является выражением-генератором, который возвращает True, если текущее число в пределах 1 и 9 кратно 6. any выполняет итерацию multiples_of_6, и когда оно встречается с 6, оно находит Truthy, поэтому он сразу возвращает True, а остальная часть multiples_of_6 не повторяется. Это мы видим при печати list(multiples_of_6), результата 7, 8 и 9.

Эта отличная вещь используется очень умно в этом ответе.


При этом базовом понимании, если мы посмотрим на ваш код, вы

any(x) and not all(x)

который гарантирует, что, по крайней мере, одно из значений - Truthy, но не все из них. Вот почему он возвращает [False, False, False]. Если вы действительно хотите проверить, не совпадают ли оба числа,

print [x[0] != x[1] for x in zip(*d['Drd2'])]

Ответ 2

Как Python any и all работы функции?

any и all принимают итераторы и возвращают True если любой и все (соответственно) элементы имеют значение True.

>>> any([0, 0.0, False, (), '0']), all([1, 0.0001, True, (False,)])
(True, True)            #   ^^^-- truthy non-empty string
>>> any([0, 0.0, False, (), '']), all([1, 0.0001, True, (False,), {}])
(False, False)                                                #   ^^-- falsey

Если итерации пустые, any возвращает False, а all возвращает True.

>>> any([]), all([])
(False, True)

Я демонстрировал all и any для студентов в классе на сегодняшний день. Они были в основном озадачены возвращаемыми значениями для пустых итерируемых элементов. Такое объяснение вызвало включение множества лампочек.

Поведение быстрого доступа

Они, any и all, как искать условия, что позволяет им прекратить оценивать. Первые примеры, которые я дал, требовали, чтобы они оценивали логическое значение для каждого элемента во всем списке.

(Обратите внимание, что литерал списка сам по себе не вычисляется лениво - вы можете получить это с помощью итератора - но это только для иллюстративных целей.)

Здесь реализация Python любого и все:

def any(iterable):
    for i in iterable:
        if i:
            return True
    return False # for an empty iterable, any returns False!

def all(iterable):
    for i in iterable:
        if not i:
            return False
    return True  # for an empty iterable, all returns True!

Конечно, реальные реализации написаны на C и намного более производительны, но вы могли бы заменить вышеприведенное и получить те же результаты для кода в этом (или любом другом) ответе.

all

all проверки для элементов, чтобы быть False (таким образом это может возвратить False), тогда это возвращает True если ни один из них не был False.

>>> all([1, 2, 3, 4])                 # has to test to the end!
True
>>> all([0, 1, 2, 3, 4])              # 0 is False in a boolean context!
False  # ^--stops here!
>>> all([])
True   # gets to end, so True!

any

any способ заключается в том, что он проверяет, чтобы элементы были True (чтобы он мог возвращать True), then it returns False, if none of them were True '.

>>> any([0, 0.0, '', (), [], {}])     # has to test to the end!
False
>>> any([1, 0, 0.0, '', (), [], {}])  # 1 is True in a boolean context!
True   # ^--stops here!
>>> any([])
False   # gets to end, so False!

Я думаю, что если вы будете помнить о кратковременном поведении, вы интуитивно поймете, как они работают, не обращаясь к Таблице Истины.

Доказательства all и any ярлык:

Сначала создайте noisy_iterator:

def noisy_iterator(iterable):
    for i in iterable:
        print('yielding ' + repr(i))
        yield i

и теперь давайте просто перебираем списки с шумом, используя наши примеры:

>>> all(noisy_iterator([1, 2, 3, 4]))
yielding 1
yielding 2
yielding 3
yielding 4
True
>>> all(noisy_iterator([0, 1, 2, 3, 4]))
yielding 0
False

Мы можем видеть all остановки на первой лживой проверке.

И any остановки на первой истинной булевой проверке:

>>> any(noisy_iterator([0, 0.0, '', (), [], {}]))
yielding 0
yielding 0.0
yielding ''
yielding ()
yielding []
yielding {}
False
>>> any(noisy_iterator([1, 0, 0.0, '', (), [], {}]))
yielding 1
True

Источник

Давайте посмотрим на источник, чтобы подтвердить вышеизложенное.

Вот источник для any:

static PyObject *
builtin_any(PyObject *module, PyObject *iterable)
{
    PyObject *it, *item;
    PyObject *(*iternext)(PyObject *);
    int cmp;

    it = PyObject_GetIter(iterable);
    if (it == NULL)
        return NULL;
    iternext = *Py_TYPE(it)->tp_iternext;

    for (;;) {
        item = iternext(it);
        if (item == NULL)
            break;
        cmp = PyObject_IsTrue(item);
        Py_DECREF(item);
        if (cmp < 0) {
            Py_DECREF(it);
            return NULL;
        }
        if (cmp > 0) {
            Py_DECREF(it);
            Py_RETURN_TRUE;
        }
    }
    Py_DECREF(it);
    if (PyErr_Occurred()) {
        if (PyErr_ExceptionMatches(PyExc_StopIteration))
            PyErr_Clear();
        else
            return NULL;
    }
    Py_RETURN_FALSE;
}

И вот источник для all:

static PyObject *
builtin_all(PyObject *module, PyObject *iterable)
{
    PyObject *it, *item;
    PyObject *(*iternext)(PyObject *);
    int cmp;

    it = PyObject_GetIter(iterable);
    if (it == NULL)
        return NULL;
    iternext = *Py_TYPE(it)->tp_iternext;

    for (;;) {
        item = iternext(it);
        if (item == NULL)
            break;
        cmp = PyObject_IsTrue(item);
        Py_DECREF(item);
        if (cmp < 0) {
            Py_DECREF(it);
            return NULL;
        }
        if (cmp == 0) {
            Py_DECREF(it);
            Py_RETURN_FALSE;
        }
    }
    Py_DECREF(it);
    if (PyErr_Occurred()) {
        if (PyErr_ExceptionMatches(PyExc_StopIteration))
            PyErr_Clear();
        else
            return NULL;
    }
    Py_RETURN_TRUE;
}

Ответ 3

Я знаю, что это старо, но я подумал, что было бы полезно показать, как эти функции выглядят в коде. Это действительно иллюстрирует логику, лучше, чем текст или таблица IMO. В действительности они реализованы на C, а не на чистом Python, но они эквивалентны.

def any(iterable):
    for item in iterable:
        if item:
            return True
    return False

def all(iterable):
    for item in iterable:
        if not item:
            return False
    return True

В частности, вы можете видеть, что результат для пустых итераций является естественным результатом, а не частным случаем. Вы также можете увидеть поведение короткого замыкания; на самом деле было бы больше работы, чтобы не было короткого замыкания.

Когда Гвидо ван Россум (создатель Python) впервые предложил добавить any() и all(), он объяснил их, просто разместив в точности указанные выше фрагменты кода.

Ответ 4

Код, о котором вы спрашиваете, исходит из моего ответа здесь. Он был предназначен для решения проблемы сравнения нескольких бит-массивов, т.е. Коллекций 1 и 0.

any и all полезны, когда вы можете положиться на "правдоподобие" значений - т.е. их значение в булевом контексте. 1 есть True, а 0 - False, удобство, которое этот ответ закрепил. 5 также будет True, поэтому, когда вы смешиваете это с вашими возможными входами... хорошо. Не работает.

Вместо этого вы можете сделать что-то вроде этого:

[len(set(x)) == 1 for x in zip(*d['Drd2'])]

Ему не хватает эстетики предыдущего ответа (мне очень понравился внешний вид any(x) and not all(x)), но он выполняет свою работу.

Ответ 5

>>> any([False, False, False])
False
>>> any([False, True, False])
True
>>> all([False, True, True])
False
>>> all([True, True, True])
True

Ответ 6

s = "eFdss"
s = list(s)
all(i.islower() for i in s )   # FALSE
any(i.islower() for i in s )   # TRUE

Ответ 7

Концепция проста:

M =[(1, 1), (5, 6), (0, 0)]

1) print([any(x) for x in M])
[True, True, False] #only the last tuple does not have any true element

2) print([all(x) for x in M])
[True, True, False] #all elements of the last tuple are not true

3) print([not all(x) for x in M])
[False, False, True] #NOT operator applied to 2)

4) print([any(x)  and not all(x) for x in M])
[False, False, False] #AND operator applied to 1) and 3)
# if we had M =[(1, 1), (5, 6), (1, 0)], we could get [False, False, True]  in 4)
# because the last tuple satisfies both conditions: any of its elements is TRUE 
#and not all elements are TRUE 

Ответ 8

list = [1,1,1,0]
print(any(list)) # will return True because there is  1 or True exists
print(all(list)) # will return False because there is a 0 or False exists
return all(a % i for i in range(3, int(a ** 0.5) + 1)) # when number is divisible it will return False else return True but the whole statement is False .