Quais ferramentas funcionais permanecem no Python 3K?
-
08-07-2019 - |
Pergunta
Eu li várias entradas sobre a queda de várias funções funcionais do futuro Python, incluindo mapa e redução.
Qual é a política oficial em relação a extensões funcionais?
A função lambda vai ficar?
Solução
Bem, o Python 3.0 e 3.1 já foram lançados, para que você possa conferir isso por si mesmo. O resultado final foi que o mapa e o filtro foram mantidos como embutidos, e o Lambda também foi mantido. A única mudança foi que a redução foi movida para o módulo Functools; você só precisa fazer
from functools import reduce
para usá-lo.
Espera-se que os lançamentos futuros 3.x permaneçam compatíveis com 3,0 e 3.1 a esse respeito.
Outras dicas
No Python 3.x, o Python continua a ter um rico conjunto de ferramentas funcionais incorporadas: compreensões de lista, expressões de gerador, iteradores e geradores e funções como any()
e all()
que têm avaliação de curto-circuito sempre que possível.
O "Ditador Benevolente para a Vida" de Python lançou a idéia de remover map()
Porque você pode reproduzir trivialmente seus efeitos com uma compreensão de lista:
lst2 = map(foo, lst)
lst3 = [foo(x) for x in lst]
lst2 == lst3 # evaluates True
Python's lambda
O recurso não foi removido ou renomeado e provavelmente nunca será. No entanto, provavelmente nunca se tornará mais poderoso. Python's lambda
é restrito a uma única expressão; Não pode incluir instruções e não pode incluir várias linhas de código Python.
Python's Plan-Old def
define um objeto de função, que pode ser passado tão facilmente quanto um lambda
objeto. Você pode até desviar o nome da função depois de defini -la, se você realmente quiser fazer isso.
Exemplo:
# NOT LEGAL PYTHON
lst2 = map(lambda x: if foo(x): x**2; else: x, lst)
# perfectly legal Python
def lambda_function(x):
if foo(x):
return x**2
else:
return x
lst2 = map(lambda_function, lst)
del(lambda_function) # can unbind the name if you wish
Observe que você pode realmente usar o "operador ternário" em um lambda
Portanto, o exemplo acima é um pouco artificial.
lst2 = map(lambda x: x**2 if foo(x) else x, lst)
Mas algumas funções multilinas são difíceis de forçar a um lambda
e são melhor tratados como funções multilinas ordinárias simples.
O Python 3.x não perdeu nenhum de seu poder funcional. Há algum sentimento geral de que as compreensões e expressões de gerador da lista provavelmente são preferíveis a map()
; em particular, as expressões geradoras às vezes podem ser usadas para fazer o equivalente a um map()
Mas sem alocar uma lista e liberá -la novamente. Por exemplo:
total = sum(map(lst, foo))
total2 = sum(foo(x) for x in lst)
assert total == total2 # same result
Em Python 2.x, o map()
aloca uma nova lista, que é somada e imediatamente libertada. A expressão do gerador obtém os valores um de cada vez e nunca amarra a memória de uma lista inteira de valores.
Em Python 3.x, map()
é "preguiçoso", então ambos são igualmente eficientes. Mas, como resultado, em Python 3.x, o exemplo ternário Lambda precisa ser forçado a expandir para uma lista:
lst2 = list(map(lambda x: x**2 if foo(x) else x, lst))
Mais fácil apenas escrever a compreensão da lista!
lst2 = [x**2 if foo(x) else x for x in lst]