Funzioni, closure e lambda
Definisca funzioni helper riutilizzabili, usi argomenti predefiniti e applichi espressioni lambda all'ordinamento e agli schemi funzionali nei problemi da colloquio
Funzioni, closure e lambda è una lezione Coding Interview Prep gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Coding Interview Prep, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Coding Interview Prep include 4 lezioni in totale.
Definizione di funzioni in Python
In Python le funzioni sono first-class: può passarle, restituirle e memorizzarle. Funzioni di supporto con nomi chiari rendono leggibile il codice dei colloqui tecnici. Gestisca prima i casi limite.
def is_palindrome(s: str) -> bool:
'''Return True if s reads the same forwards and backwards.'''
s = s.lower()
return s == s[::-1]
print(is_palindrome('Racecar')) # True
print(is_palindrome('hello')) # False
# Functions as values
checks = [is_palindrome]
print(checks[0]('level')) # TrueArgomenti predefiniti e keyword
I valori predefiniti permettono a chi chiama la funzione di omettere alcuni argomenti. Tuttavia, non usi mai un valore predefinito mutabile, come una list: tutti i chiamanti lo condividerebbero. La soluzione è usare None come valore predefinito e creare la list all'interno. Veda il codice.
# WRONG: shared mutable default
def bad_append(val, lst=[]):
lst.append(val)
return lst
print(bad_append(1)) # [1]
print(bad_append(2)) # [1, 2] surprise!
# CORRECT: use None sentinel
def good_append(val, lst=None):
if lst is None:
lst = []
lst.append(val)
return lst
print(good_append(1)) # [1]
print(good_append(2)) # [2]*args e **kwargs
*args raccoglie gli argomenti posizionali aggiuntivi in una tuple; **kwargs raccoglie quelli keyword aggiuntivi in un dict. L'asterisco consente inoltre di decomprimere una sequenza quando si chiama una funzione.
def total(*args):
return sum(args)
print(total(1, 2, 3)) # 6
print(total(1, 2, 3, 4)) # 10
# Unpack a list as positional args
point = [3, 7]
print(max(*point)) # 7
# **kwargs
def greet(**kwargs):
name = kwargs.get('name', 'World')
return f'Hello, {name}!'
print(greet(name='Alice')) # Hello, Alice!Espressioni lambda
Una lambda è una piccola funzione di una sola riga: lambda params: expression. È perfetta come key rapida in sorted o max. Per qualcosa di più complesso, un def con nome è più leggibile.
# Lambda as sort key
pairs = [(1, 3), (2, 1), (3, 2)]
sorted_by_second = sorted(pairs, key=lambda p: p[1])
print(sorted_by_second) # [(2,1),(3,2),(1,3)]
# Lambda with map
double = list(map(lambda n: n * 2, [1, 2, 3]))
print(double) # [2, 4, 6]
# Named function is clearer for complex logic
def sort_key(p):
return (p[1], -p[0]) # secondary sort
print(sorted(pairs, key=sort_key))Funzioni annidate e closure
Una closure è una funzione che ricorda le variabili della funzione che la contiene. Definisca una funzione di supporto all'interno di un'altra funzione: potrà usare le variabili esterne, una tecnica utile per DFS.
def make_counter(start=0):
count = [start] # list to allow mutation
def increment():
count[0] += 1
return count[0]
return increment
counter = make_counter()
print(counter()) # 1
print(counter()) # 2
# Alternative: nonlocal keyword
def make_counter2():
count = 0
def increment():
nonlocal count
count += 1
return count
return incrementClosure nella DFS ricorsiva
Un pattern comune consiste nel definire una funzione di supporto dfs all'interno della funzione principale e consentirle di raccogliere i risultati in una variabile esterna. La funzione interna forma una closure su quell'ambito.
def max_depth(root):
'''Closure pattern for tree DFS.'''
max_d = [0] # mutable container for closure
def dfs(node, depth):
if node is None:
return
max_d[0] = max(max_d[0], depth)
dfs(node.left, depth + 1)
dfs(node.right, depth + 1)
dfs(root, 1)
return max_d[0]
# This pattern avoids a class or global state.functools.lru_cache per la memoizzazione
lru_cache (o @cache dalla versione 3.9 in poi) ricorda i risultati di una funzione in base ai suoi argomenti, trasformando il Fibonacci ingenuo da O(2^n) a O(n). Gli argomenti devono essere hashable, quindi usi tuple.
from functools import lru_cache
@lru_cache(maxsize=None)
def fib(n):
if n <= 1:
return n
return fib(n - 1) + fib(n - 2)
print(fib(40)) # 102334155 fast!
print(fib.cache_info()) # hits, misses, sizeFunzioni di ordine superiore
Una funzione di ordine superiore accetta o restituisce una funzione. sorted, map e filter ne sono tutti esempi. Scriverne una propria consente di astrarre i pattern ripetuti. Il codice mostra la composizione.
def apply_twice(f, x):
return f(f(x))
print(apply_twice(lambda n: n * 2, 3)) # 12 (3*2*2)
# Composing transformations
def compose(f, g):
return lambda x: f(g(x))
double = lambda n: n * 2
add_one = lambda n: n + 1
double_then_add = compose(add_one, double)
print(double_then_add(5)) # 11 ((5*2)+1)Ricorsione con funzioni di supporto
Molte soluzioni associano una funzione esterna, che gestisce l'inizializzazione e i casi limite, a una funzione di supporto interna, che esegue la ricorsione. API pubblica pulita e logica isolata. Veda il codice.
def flatten(nested):
'''Flatten an arbitrarily nested list.'''
result = []
def _flatten(lst):
for item in lst:
if isinstance(item, list):
_flatten(item)
else:
result.append(item)
_flatten(nested)
return result
print(flatten([1, [2, [3, 4], 5], 6]))
# [1, 2, 3, 4, 5, 6]Funzioni parziali con functools.partial
functools.partial preimposta alcuni argomenti e restituisce un nuovo oggetto chiamabile. È utile quando un'API richiede una funzione senza argomenti, ma lei deve fissare un parametro.
from functools import partial
def power(base, exp):
return base ** exp
square = partial(power, exp=2)
cube = partial(power, exp=3)
print(square(5)) # 25
print(cube(3)) # 27
print(list(map(square, [1, 2, 3, 4]))) # [1, 4, 9, 16]Lambda per comparatori personalizzati
Python 3 ha eliminato i comparatori a due argomenti, ma cmp_to_key li reintroduce per gli ordinamenti complessi, ad esempio per disporre i numeri in modo che la loro concatenazione sia la più grande possibile. Veda il codice.
from functools import cmp_to_key
def largest_number(nums):
def compare(a, b):
if a + b > b + a: return -1
if a + b < b + a: return 1
return 0
strs = list(map(str, nums))
strs.sort(key=cmp_to_key(compare))
result = ''.join(strs)
return '0' if result[0] == '0' else result
print(largest_number([3, 30, 34, 5, 9])) # '9534330'Verifica rapida
Verifica rapida: è il momento di dimostrare ciò che ha imparato su funzioni, closure e lambda. Faccia un respiro e inizi. 🚀
Riepilogo della lezione
Riepilogo: non usi mai valori predefiniti mutabili (usi None), le closure consentono alle funzioni di supporto interne di accedere alle variabili esterne per la DFS e gli strumenti di functools, come lru_cache, permettono di realizzare soluzioni rapide.
Domande Frequenti
La lezione «Funzioni, closure e lambda» è gratuita?
Sì — il testo completo di «Funzioni, closure e lambda» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Coding Interview Prep, passa a CoddyKit PRO. Il corso Coding Interview Prep include 4 lezioni in totale.
Cosa imparerò in «Funzioni, closure e lambda»?
Definisca funzioni helper riutilizzabili, usi argomenti predefiniti e applichi espressioni lambda all'ordinamento e agli schemi funzionali nei problemi da colloquio Eserciti Coding Interview Prep con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Coding Interview Prep?
Non è richiesta alcuna esperienza precedente. Coding Interview Prep su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.
Quanto tempo richiede la lezione «Funzioni, closure e lambda»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Coding Interview Prep?
Sì. Ogni lezione Coding Interview Prep include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Liste, tuple e slicing
- Dizionari e set in Python
- Comprehension e funzioni built-in
- Funzioni, closure e lambda