and
en or
retourneren 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 any
en all
toe 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 any
en all
implementeerde, reageerdespecifiek ingaand op waarom any
en any
zich niet gedragen als and
en 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%
and
en or
kunnen zo worden gedefinieerd dat ze altijdeen van hun operanden retourneren. Het is echter niet verstandig om any
en all
altijd te definiëren om een waarde uit hun invoerreeks te retourneren: dit kunnen ze met name niet doen als de lijst leeg is. Zowel any
als all
hebben momenteel een goed gedefinieerd resultaat in deze situatie: any
retourneert False en all
retourneert 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.8
en de introductie van toewijzingsexpressies (PEP 572)(:=
operator), we kunnen ook expliciet een getuigevastleggen van een any
uitdrukking 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 and
en or
was historisch nuttig als een druppel voor de toenmalige, voorwaardelijke uitdrukking.