Forum >> Programmazione Python >> Scripting >> consiglio in stile funzionale

Pagina: 1

Ciao,
sto scrivendo da poco codice in stile funzionale ed avrei qualche dubbio
per tradurre

if obsoleto:
print('aggiorna')
aggiorna()

è meglio scrivere:

1. obsoleto and print('aggiorna') is None and aggiorna()

2. obsoleto and not print('aggiorna') and aggiorna()

3. obsoleto and (print('aggiorna') or aggiorna())

La (1) forse è più leggibile, la (2) sembra non voler stampare ma è più concisa e la (3) ancora di più, ma può trarre in inganno.

Qual'è la migliore soluzione? Ce ne sono altre?

Buon anno e grazie.
La 3 è più concisa ma richiede un passaggio mentale in più (la soluzione dell'OR).

Personalmente trovo più leggibile la prima, magari abbreviata in:
obsoleto  and  [print('aggiorna')]  and  aggiorna()

*** Il codice va evidenziato con il simbolo di fianco ai colori per non perdere l'indentazione ***
Personalmente trovo più leggibile la prima, magari abbreviata in:
obsoleto  and  [print('aggiorna')]  and  aggiorna()


Bella!

Mi piace e mi offre lo spunto per affrontare un altro nodo, che da tempo dovrei sciogliere: lista o tupla?

Nel codice scritto sopra genero una lista, che si prende spazio in memoria dati per 4 elementi (in previsione di eventuali aggiunte che non verranno mai fatte).

Non è più economica la soluzione:
obsoleto  and  (print('aggiorna'),) and  aggiorna()
generando una tupla che prende spazio in memoria programma, veloce e senza neppure scomodare il kernel, per 1 solo elemento invariabile?

Propongo un altro esempio:
Devo passare ad una funzione un argomento composto da una lista che non verrà modificata.
funzione([oggetto.nome for oggetto in listaoggetti])

Ma non è migliore, in ogni senso, scrivere:
funzione(tuple(oggetto.nome for oggetto in listaoggetti))
?

Non credo che quella tupla occupi solo "memoria programma" come se fosse una const in C. Bisognerebbe vedere il decompilato bytecode, ma credo che, al pari della lista, venga creata a runtime ad ogni valutazione dell'espressione logica. Peggio ancora, potrebbe essere ricreata ogni volta anche la stringa. Da quanto leggo le ottimizzazioni pensate come se si stesse lavorando con allocazione statica non hanno molto senso in Python o potrebbero avere un controintuitivo effetto opposto (non conoscendo esattamente cosa gira sotto).

*** Il codice va evidenziato con il simbolo di fianco ai colori per non perdere l'indentazione ***
"Python alla massima potenza" di Micha Gorelik e Ian Ozvald

(pag.66)
' ... 3. Le tuple vengono salvate in una cache del runtime Python; questo significa che non devono comunicare al kernel di riservare della memoria ogni volta che vogliamo usarne una.'

(pag.67)
'... Inoltre, l'immutabilità di una tupla ... la rende una struttura dati molto "leggera" ... per le liste è necessario più spazio in memoria e più attività di calcolo.'

(pag.68 )
' ... Equazione per l'allocazione di liste in Python 2.7

M = (N >> 3) + (N < 9 ? 3 : 6)

N 0 1-4 5-8 9-16 17-25 26-35 36-46 ... 991-1120
M 0 4-8 16 25 35 46 ... 1120
>>> import timeit
>>> timeit.timeit('x = list(range(10))') / timeit.timeit('x = tuple(range(10))')
>>> 1.326 ...
>>> timeit.timeit('x = list(range(5))') / timeit.timeit('x = tuple(range(5))')
>>> 1.329 ...
Mi scuso per il messaggio rotto in due parti, ma ho ancora problemi con l'editor del forum (come si esce da quote?)

Infatti il codice non fa parte del testo del libro, l'ho scritto io, ... e si vede!
Spero di avere trascritto in modo corretto (NO copia incolla dal testo in prestito) e soprattutto di non aver infranto i diritti d'autore!

In ogni caso si può ben vedere dal test che occorre il 32% di tempo in più per allocare una lista piuttoto che una tupla, differenza che aumenta con liste più piccole, per liste monodimesionali (range(1)) è addirittura il 52%!

Quindi tante piccole tuple, quando possibile, migliorano le prestazioni. Senza parlare dell'occupazione di memoria, come si vede dalla tabella di allocazione.


(mi riscuso per l'interruzione, il gelo intorpidisce le dita.)

dicevo: l'occupazione di memoria della lista prevede lo spazio per l'aggiunta di altri elementi, forse solo se si usa append, ma credo sia implicito l'uso di append (questa parte non l'ho ben chiara).

Sicuramente, quando lo spazio riservato per le aggiunte termina, la lista verrà copiata e riallocata in un nuovo spazio di memoria contiguo, altro tempo da aggiungere e inevitabile frammentazione della memoria.

Comunque devo ringraziarti, la soluzione al problema è semplice e bella!
e se non mi sbaglio la lista generata, non essendo assegnata, verrà cancellata ben presto.

Peccato che la mia variante abbia quella virgola, ...fastidiosa.

Mica si può avere tutto! (se non conosci Mica: "L'el fradel del Pota").


Pagina: 1



Esegui il login per scrivere una risposta.