Last chance! 50% off DataCamp Premium
Sale ends in
Un’esigenza comune nei programmi Python è verificare se almeno un elemento di una struttura dati sia True.
Sebbene sia possibile scrivere un ciclo per iterare su un iterabile e verificare se ciascun elemento è valutato come True o False, la funzione any() di Python è un modo più efficiente e “pythonic” per ottenere lo stesso risultato.
Questo tutorial esplora la funzione incorporata any() di Python e mostra diversi esempi e casi d’uso.
any() di Python?La funzione any() è una delle funzioni built-in. Accetta un iterabile come una lista o una tupla e restituisce True se almeno un valore nell’iterabile è truthy. Un valore truthy è valutato come True quando convertito in booleano con bool(). Se tutti i valori nell’iterabile sono falsy, any() restituisce False:
print(any([True, False, False, True]))
print(any([False, False, False, False]))
print(any([0, 0, 5, 0]))
True
False
True
L’iterabile può contenere valori booleani o altri oggetti, poiché tutti gli oggetti sono valutati come True o False quando convertiti in booleano. Nel terzo esempio, la lista include quattro interi. L’intero 0 è falsy, ma tutti i numeri diversi da zero sono truthy. Per capire meglio la differenza tra valori truthy e falsy, leggi questo articolo sugli operatori logici in Python.
Se l’iterabile è vuoto, any() restituisce False perché non ci sono valori truthy in un iterabile vuoto:
print(any([]))
False
La prossima sezione approfondisce il funzionamento di any().
any()?La funzione built-in any() accetta come argomento qualsiasi iterabile. Un iterabile è qualsiasi struttura dati su cui Python può scorrere con un ciclo.
Considera la seguente tupla:
an_iterable = ("", 0.0, "DataCamp", False, [])
La tupla include diversi oggetti di tipi differenti. Molti di questi oggetti sono falsy:
""0.0False[]Questi oggetti sono falsy perché vengono valutati come False quando passati a bool().
La stringa non vuota "DataCamp" è truthy.
Un modo semplice per verificare se almeno un elemento è truthy è usare un ciclo for:
def check_if_contains_truthy(data):
output = False
for item in data:
if item:
output = True
return output
print(check_if_contains_truthy(an_iterable))
True
Tuttavia, questo è inefficiente perché la funzione deve solo verificare se c’è almeno un valore truthy. Una volta trovato, non è necessario continuare a controllare il resto degli elementi dell’iterabile. La funzione può essere modificata per restituire il risultato non appena trova il primo valore truthy:
def check_if_contains_truthy(data):
for item in data:
if item:
return True
return False
print(check_if_contains_truthy(an_iterable))
True
Un’istruzione return interrompe l’esecuzione della funzione. Quindi, quando la funzione trova il primo valore truthy, restituisce True e non continua a iterare sull’iterabile. La funzione restituisce False solo se il ciclo for scorre tutti gli elementi dell’iterabile e nessuno è truthy.
La funzione built-in any() segue un modello simile e “short-circuita” quando trova il primo valore truthy. Questa valutazione pigra evita operazioni non necessarie e migliora le prestazioni. La any() di Python è una versione più efficiente della funzione mostrata sopra. Questa maggiore efficienza è confermata usando la funzione timeit() del modulo timeit, che misura quanto impiega Python a eseguire un’istruzione:
from timeit import timeit
print("Execution time for 'check_if_contains_truthy()'")
print(
timeit(
"check_if_contains_truthy(an_iterable)",
number=10_000_000,
globals=globals(),
)
)
print("Execution time for 'any()'")
print(
timeit(
"any(an_iterable)",
number=10_000_000,
globals=globals(),
)
)
Execution time for 'check_if_contains_truthy()'
0.6335119580035098
Execution time for 'any()'
0.39488654200249584
Il primo argomento di timeit() è una stringa che contiene l’istruzione da eseguire. Il secondo argomento determina quante volte eseguire l’istruzione. In questo esempio, entrambe le istruzioni sono eseguite 10.000.000 di volte per ottenere tempi significativi. L’argomento finale passa le variabili globali alla funzione timeit().
La any() di Python è più veloce di check_if_contains_truthy(). Usare any() per verificare se un iterabile ha almeno un valore truthy è più “pythonic” ed efficiente rispetto a un ciclo for.
any()Vediamo alcuni casi d’uso della any() di Python.
Considera una serie di input utente raccolti in una lista o tupla. Un programma può dover verificare se almeno uno degli input è valido, ad esempio se è una stringa non vuota:
user_inputs = ["", "10.99", ""]
if any(user_inputs):
print("At least one valid input present")
# Rest of code...
else:
print("There are no valid inputs")
At least one valid input present
Poiché una delle stringhe non è vuota, any() restituisce True ed è eseguito il codice nel blocco if.
La funzione built-in any() può essere usata per controllare se almeno un file in una lista di nomi file esiste in una directory:
from pathlib import Path
files = ["article.md", "use_any.py", "scratch.py", "test_file.txt"]
cwd = Path.cwd()
# Create a test file to test code
Path("test_file.txt").write_text("This is a test file")
if any(Path(file).exists() for file in files):
print("At least one of the files exists")
# Rest of code…
else:
print("None of the files exist")
At least one of the files exists
Il codice recupera la directory di lavoro corrente usando il modulo pathlib e Path.cwd(). Crea un file chiamato test_file.txt nella directory di lavoro per consentire di testare facilmente questo codice. La any() di Python è usata per verificare se almeno uno dei nomi file esiste nella directory di lavoro corrente.
La funzione built-in any() può anche essere usata con un’espressione generatrice come argomento per filtrare elementi da un iterabile. In questo esempio, any() cerca almeno una voce in una lista di dizionari che rappresentano una persona con età inferiore a 18:
records = [
{"name": "Sarah", "age": 23},
{"name": "Jake", "age": 30},
{"name": "Paul", "age": 17},
]
if any(record["age"] < 18 for record in records):
print("There's at least one minor.")
else:
print("All records are adults.")
There's at least one minor.
L’espressione generatrice produce True o False a seconda del valore corrispondente alla chiave "age" di ciascun dizionario. Un’espressione generatrice può essere usata in any() perché è iterabile.
any() di PythonL’esempio precedente può anche dimostrare che any() è valutata in modo pigro. Considera la seguente modifica alla lista di dizionari:
records = [
{"name": "Sarah", "age": 23},
{"name": "Jake", "age": 30},
{"name": "Paul", "age": 17},
{"name": "Jill"},
]
if any(record["age"] < 18 for record in records):
print("There's at least one minor.")
else:
print("All records are adults.")
There's at least one minor.
Il quarto dizionario in records non contiene un elemento con chiave "age". Tuttavia, il codice non solleva un errore quando prova a recuperare il valore corrispondente a "age" per questo elemento perché any() ha trovato un valore truthy in precedenza. La funzione fa short-circuit quando incontra il primo valore truthy.
Il codice solleva un KeyError se il dizionario a cui manca la chiave "age" compare prima di qualsiasi elemento con età inferiore a 18:
records = [
{"name": "Jill"},
{"name": "Sarah", "age": 23},
{"name": "Jake", "age": 30},
{"name": "Paul", "age": 17},
]
if any(record["age"] < 18 for record in records):
print("There's at least one minor.")
else:
print("All records are adults.")
Traceback (most recent call last):
...
if any(record["age"] < 18 for record in records):
~~~~~^^^^^^
KeyError: 'age'
Questo esempio serve a dimostrare il comportamento di short-circuit quando si usa any() in Python. Esiste un’alternativa se il codice non dovrebbe sollevare eccezioni per elementi senza la chiave "age". È possibile usare il metodo del dizionario .get() con un valore predefinito invece di accedere al valore con la notazione tra parentesi quadre. L’istruzione if può essere sostituita con la seguente versione se il comportamento predefinito è considerare che le voci senza età non siano minorenni:
if any(record.get("age", 18) < 18 for record in records):
# ...
Se il codice deve considerare qualsiasi voce senza età come minorenne, il valore predefinito deve essere inferiore a 18.
any() vs. all()La any() di Python ha una funzione complementare, all(). Anche questa funzione built-in accetta un iterabile e restituisce True se tutti gli elementi dell’iterabile sono truthy.
Considera un esempio visto in precedenza in questo tutorial per validare gli input utente. La any() di Python è utile se l’applicazione richiede almeno un input valido. Tuttavia, si può usare all() se tutti gli input utente devono essere validi:
user_inputs = ["", "10.99", ""]
if any(user_inputs):
print("At least one valid input present")
# Rest of code...
else:
print("There are no valid inputs")
if all(user_inputs):
print("All inputs are valid")
# Rest of code...
else:
print("Not all inputs are valid")
At least one valid input present
Not all inputs are valid
Tuttavia, se tutte le stringhe negli input utente sono non vuote, all() restituisce True:
user_inputs = ["5.99", "10.99", "19.99"]
# …
At least one valid input present
All inputs are valid
Analogamente a any(), la funzione built-in all() è valutata in modo pigro. La funzione fa short-circuit quando trova il primo valore falsy.
La any() di Python verifica se uno qualsiasi degli elementi in un iterabile è truthy. La funzione restituisce True se almeno un elemento nell’iterabile è True o viene valutato come True quando convertito in booleano. Anche se lo stesso risultato si può ottenere con un ciclo, questa funzione built-in offre una soluzione più leggibile ed efficiente.
Ho studiato Fisica e Matematica a livello UG presso l’Università di Malta. Poi mi sono trasferito a Londra e ho conseguito il dottorato in Fisica all’Imperial College. Ho lavorato su nuove tecniche ottiche per immagini della retina umana. Ora mi concentro sullo scrivere di Python, comunicare su Python e insegnare Python.
Impara la data science da zero!
Corso
Corso
Corso

blog
Abid Ali Awan
10 min
blog
Tim Lu
12 min

blog
Abid Ali Awan
15 min