Python'un tüm fonksiyonları nasıl çalışır?


225

any()Ve all()Python yerleşik işlevlerin nasıl çalıştığını anlamaya çalışıyorum .

Ben herhangi bir değer farklı ise o zaman dönecek Trueve hepsi aynı ise geri döner böylece tuples karşılaştırmaya çalışıyorum False. Bu durumda [Yanlış, Yanlış, Yanlış] geri dönmek için nasıl çalışıyorlar?

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

Bildiğim kadarıyla bu çıktı

# [False, True, False]

(1,1) aynı, (5,6) farklı ve (0,0) aynı.

Neden tüm tuples için False olarak değerlendiriliyor?


4
any (yinelenebilir): Truthy nesnesinin ilk karşılaşmasında true değerini döndürür, else false değerini döndürür. all (yinelenebilir): falsy nesnesinin ilk karşılaşmasında flase döndürür else başka döner.
shadow0359

Yanıtlar:


375

Sen kabaca aklınıza gelebilecek anyve allmantıksal dizi olarak orve andsırasıyla operatörler.

hiç

anyöğelerden en az biri Gerçek Trueolduğunda geri dönecektir . Gerçek Değer Testi hakkında bilgi edinin .

herşey

allTrueyalnızca tüm öğeler Gerçek olduğunda geri döner.

Doğruluk tablosu

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

Not 1: Boş yinelenebilir durum, resmi belgelerde şöyle açıklanmaktadır:

any

TrueYinelenebilir öğenin herhangi bir öğesi doğruysa dön . Yinelenebilir boşsa, geri dönFalse

Öğelerin hiçbiri doğru olmadığından False, bu durumda geri döner .

all

TrueYinelenebilir öğenin tüm öğeleri doğruysa ( veya yinelenebilir boşsa ) geri dönün .

Öğelerin hiçbiri yanlış olmadığından True, bu durumda geri döner .


Not 2:

Bir diğer önemli şey hakkında bilmek anyve allbu kısa devre yürütme, Sonucu bildikleri anı olacak vardır. Avantajı, tüm tekrarlanabilir özelliklerin tüketilmesine gerek olmamasıdır. Örneğin,

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

Burada, (not (i % 6) for i in range(1, 10))döner bir jeneratör ifadesidir True1 ile 9 içinde mevcut sayısı 6 bir katı ise, anydolaşır multiples_of_6karşıladığı zaman ve 6, bir Truthy değeri bulur, hemen o kadar döner True, ve dinlenme multiples_of_6tekrarlanır değildir. Yani biz yazdırırken gördüğüm bu list(multiples_of_6), sonucunu 7, 8ve 9.

Bu mükemmel şey bu cevapta çok akıllıca kullanılıyor .


Bu temel anlayışla, kodunuza bakarsak,

any(x) and not all(x)

bu da, değerlerden en azından birinin Gerçeği olduğunu fakat hepsinin değil olmasını sağlar. Bu yüzden geri dönüyor [False, False, False]. Her iki sayının aynı olup olmadığını gerçekten kontrol etmek istiyorsanız,

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

@anyone: Boş liste için True döndürdüğü durum dışında hepsini kullanmam gerekirse kabul edilemez, ne yapacağız? Liste boşsa True vermenin arkasındaki mantığı anlamıyorum ... all all [[]) == True
JavaSa

1
@JavaSa Listenin boş olup olmadığını açıkça kontrol edebilirsiniz. Böyle bir şeyin bool(data) and all(...)çalışması gerektiğine inanıyorum .
thefourtheye

43

Python'lar anyve allfonksiyonlar nasıl çalışır?

anyve allyinelenebilirleri alın ve Trueöğelerin herhangi biri (tümü) ise geri dönün 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

Yinelenebilirler boşsa, anygeri döner Falseve allgeri döner True.

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

Ben gösteren edildi allve anysınıftaki öğrencilere bugün için. Çoğunlukla boş tekrarlanabilirler için dönüş değerleri konusunda kafası karışıktı. Bu şekilde açıklamak birçok ampulün yanmasına neden oldu.

Kısayol davranışı

Onlar anyve allonları değerlendiren durdurmak için izin veren bir durum için her iki bakış. Verdiğim ilk örnekler, tüm listedeki her bir öğe için boole değerlerini değerlendirmelerini gerektiriyordu.

(Liste değişmezine dikkat edin bilgisinin kendisinin tembel olarak değerlendirilmediğine dikkat edin - bunu bir Yineleyici ile alabilirsiniz - ancak bu yalnızca açıklama amaçlıdır.)

İşte tüm Python uygulamaları:

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!

Tabii ki, gerçek uygulamalar C ile yazılır ve çok daha performanslıdır, ancak yukarıdakilerin yerine geçebilir ve bu (veya başka herhangi bir) cevaptaki kod için aynı sonuçları alabilirsiniz.

all

allöğelerin olup olmadığını kontrol eder False(böylece geri dönebilir False), sonra Truehiçbiri olmadıkça geri döner 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

Yolu anyişleri elemanlarının aynı çekleri olmak olmasıdır Trueo dönebilmek ( True), then it returnsYanlışif none of them were etmesidir True`ya dönebilir.

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

Kısa devre davranışını aklınızda tutarsanız, bir Doğruluk Tablosuna başvurmak zorunda kalmadan sezgisel olarak nasıl çalıştıklarını anlayacaksınız.

Kanıtı all ve anykısayol:

İlk olarak, bir noisy_iterator oluşturun:

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

ve şimdi örneklerimizi kullanarak gürültülü listeler üzerinden tekrarlayalım:

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

Görebiliriz allİlk Yanlış boole kontrolünde durakları .

Ve anyilk Gerçek boole kontrolünde durur:

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

Kaynak

Yukarıdakileri doğrulamak için kaynağa bakalım.

İşte kaynağı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;
}

Ve işte kaynakall :

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

1
Not: Bu matematik tahminleri ile tutarlıdır: "herkes için" ve "mevcut". Karışıklık "HERKES İÇİN" ve "HERHANGİ" başka bağlamlarda eş ... olduklarını olabilir en.wikipedia.org/wiki/List_of_logic_symbols
mcoolive

1
@ thanos.a içinde Python/bltinmodule.c- yukarıdakilere ekledim.
Aaron Hall

14

Bu eski olduğunu biliyorum, ama bu fonksiyonların kodda neye benzediğini göstermek için yararlı olabileceğini düşündüm. Bu gerçekten mantığı, metinden veya bir tablo IMO'sundan daha iyi gösterir. Gerçekte, saf Python yerine C'de uygulanırlar, ancak bunlar eşdeğerdir.

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

Özellikle, boş yinelenebilirler için sonucun özel bir durum değil, sadece doğal sonuç olduğunu görebilirsiniz. Ayrıca kısa devre davranışını da görebilirsiniz; aslında orada daha iş olurdu değilkısa devre .

Guido van Rossum (Python'un yaratıcısı) ilk kez eklemeyi önerdiğinde any()veall() tam olarak yukarıdaki kod snippet'lerini göndererek bunları açıkladı.


10

Söz konusu kod, burada verilen cevabımdan geliyor . Birden fazla bit dizisini karşılaştırma problemini çözmeyi amaçladı - yani 1ve 0.

anyve allsen değerler "doğruluğuna" güvenebilirsiniz zaman faydalıdır - yani bir boolean bağlamda onların değer. 1 Trueve 0, Falsecevabın kullandığı bir kolaylıktır. 5 de olur True, bu yüzden bunu olası girişlerinize karıştırdığınızda ... iyi. Çalışmıyor.

Bunun yerine böyle bir şey yapabilirsiniz:

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

Önceki cevabın estetiğinden yoksundur ( görünüşünü gerçekten beğendim any(x) and not all(x)), ama işi hallediyor.


Colbert'in etkisi CS / CE'ye ulaşıyor: en.wikipedia.org/wiki/Truthiness ? Bulanık mantıktan mı bahsediyoruz? : D
Geof Sawaya

OP'nin Truedeğerlerin ne zaman farklı olduğunu sorduğu gibi, setin uzunluğu 1 değil 2 olmalıdır.
wombatonfire

@wombatonfire haha ​​iyi yakala. 7 yaşındaki cevabımı
ayarladım

İyi cevaplar yaşlanmıyor :) Bir set ile güzel bir yaklaşım.
wombatonfire

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

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

1

Kavram basit:

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 

0
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 .
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.