Waarom retourneert python `any` een bool in plaats van de waarde?

anden orretourneren het laatste element dat ze hebben geëvalueerd, maar waarom heeft de ingebouwde functie van Python geen any?

Ik bedoel, het is vrij eenvoudig om jezelf op deze manier te implementeren, maar ik vraag me nog steeds af waarom.

def any(l):
    for x in l:
        if x:
            return x
    return x

bewerken:

Om aan de onderstaande antwoorden toe te voegen, hier is een feitelijk citaat van dezelfde mailinglijst van uw machtige keizer over deze kwestie:

Of je altijd True en False moet retourneren of de eerste die faalt/past
element? Ik speelde daar ook mee voordat ik blogde, en realiseerde me dat de
eindgeval (als de reeks leeg is of als alle elementen de test niet doorstaan)
kan nooit naar tevredenheid aan het werk worden gebracht: Geen kiezen voelt raar als
het argument is een herhaling van bools, en False kiezen voelt raar als
het argument is een herhaling van niet-bool-objecten.

Guido van Rossum (startpagina: http://www.python.org/~guido/)


Antwoord 1, autoriteit 100%

Dit probleem kwam op de mailinglijst van Python-ontwikkelaars in 2005, toen Guido Van Rossum voorstelde om anyen alltoe te voegen aan Python 2.5.

Bill Janssen heeft gevraagddat ze worden geïmplementeerd als

def any(S):
    for x in S:
        if x:
            return x
    return S[-1]
def all(S):
    for x in S:
        if not x:
            return x
    return S[-1]

Raymond Hettinger, die anyen allimplementeerde, reageerdespecifiek ingaand op waarom anyen anyzich niet gedragen als anden or:

In de loop van de tijd heb ik feedback gekregen over deze en andere itertools-recepten.
Niemand heeft bezwaar gemaakt tegen de True/False-retourwaarden in die recepten of
in Guido’s versie.

Guido’s versie komt overeen met de normale verwachting dat alles een is
predikaat. Het vermijdt ook het soort fouten/verwarring dat mensen
momenteel ervaring met Python’s unieke implementatie van “en” en
“of”.

Het laatste element teruggeven is niet slecht; het is gewoon raar, onverwacht, en
niet voor de hand liggend. Weersta de drang om lastig te worden met deze.

De mailinglijst was het grotendeels eens en liet de implementatie zoals je die vandaag ziet.


Antwoord 2, autoriteit 46%

anden orkunnen zo worden gedefinieerd dat ze altijdeen van hun operanden retourneren. Het is echter niet verstandig om anyen allaltijd te definiëren om een ​​waarde uit hun invoerreeks te retourneren: dit kunnen ze met name niet doen als de lijst leeg is. Zowel anyals allhebben momenteel een goed gedefinieerd resultaat in deze situatie: anyretourneert False en allretourneert True. Je zou gedwongen zijn om somseen booleaanse waarde te retourneren en somseen item uit de reeks, wat een onaangename en verrassende interface oplevert. Het is veel beter om eenvoudig en consistent te zijn.


Antwoord 3, autoriteit 23%

Het starten van Python 3.8en de introductie van toewijzingsexpressies (PEP 572)(:=operator), we kunnen ook expliciet een getuigevastleggen van een anyuitdrukking of een tegenvoorbeeldvan een all-uitdrukking:


Om een ​​paar voorbeelden te citeren uit de PEP-beschrijving:

if any(len(long_line := line) >= 100 for line in lines):
  print("Extremely long line:", long_line)
if all((nonblank := line).strip() == '' for line in lines):
  print("All lines are blank")
else:
  print("First non-blank line:", nonblank)

4

Het is niet meteen duidelijk dat any‘s-waarde onjuist of een van de waarden in de invoer zou kunnen zijn. Ook zouden de meeste toepassingen eruit zien

tmp = any(iterable)
if tmp:
   tmp.doSomething()
else:
   raise ValueError('Did not find anything')

Dat is kijk voordat u springt en dus unpypythonic. Vergelijken met:

next(i for i in iterable if i).doSomething()
# raises StopIteration if no value is true

Het gedrag van anden orwas historisch nuttig als een druppel voor de toenmalige, voorwaardelijke uitdrukking.

Other episodes