Alle volte capita che quello che viene dato va quasi bene ma non esattamente come si vorrebbe; per esempio concatenare stringhe:
$ py3
>>> st1 = 'prima stringa'
>>> st2 = 'seconda'
>>> st3 = ''
>>> st4 = 'quarta'
>>> print(st1, '\n', st2, '\n', st3, '\n', st4)
prima stringa
seconda
quarta
>>>
Va quasi bene ma no perché Python introduce un blank tra gli elementi che scrive. Sì, ci sono rimedi anche semplici, come usare + per concatenare le stringhe ma forse si riesce a fare meglio (o comunque diversamente).
Con un po' di Stack Overflow, per la dritta, poi modificata, ecco:
>>> lst = ['a', 'b', 'c', 'd']
>>> list(map(' '.join, zip(*([iter(lst)]*(len(lst))))))
['a b c d']
>>>
OK, nel nostro caso diventa:
>>> lst = [st1, st2, st3, st4]
>>> print(list(map('\n'.join, zip(*([iter(lst)]*(len(lst))))))[0])
prima stringa
seconda
quarta
>>>
Uh! conviene definire una funzione, strcat(lst, sep) che ritorna la stringa degli elementi di lst separati da sep.
Nota: mi dicono che mettere le parentesi per le funzioni --così strcat()-- non è pythonico; se mi ricordo non lo farò più e scriverò strcat.
>>> def strcat(lst, sep):
... return list(map(sep.join, zip(*([iter(lst)]*(len(lst))))))[0]
...
>>> strcat(['1', '2', '3', '4', '5'], ' - ')
'1 - 2 - 3 - 4 - 5'
>>> lst = [st1, st2, st3, st4]
>>> stp = strcat(lst, '\n')
>>> stp
'prima stringa\nseconda\n\nquarta'
>>> print(stp)
prima stringa
seconda
quarta
>>>
strcat è composta da una sola istruzione, si può lambdarla:
>>> strcat = lambda lst, sep : list(map(sep.join, zip(*([iter(lst)]*(len(lst))))))[0]
<function <lambda> at 0x7f3332d6d8c8>
>>> strcat(['1', '2', '3', '4', '5'], ' - ')
'1 - 2 - 3 - 4 - 5'
>>>
strcat adesso funziona solo con liste tutte di tipo str, da modificare rendendo str gli elementi della lista, compito per map:
>>> st = [1, 2, 3, 4, 'stringa', 6, 7.89]
>>> list(map(str, st))
['1', '2', '3', '4', 'stringa', '6', '7.89']
>>>
Inserendo map ottengo la versione corretta
>>> strcat = lambda lst, sep : list(map(sep.join, zip(*([iter(map(str, lst))]*(len(lst))))))[0]
da provare prima di subito:
>>> strcat = lambda lst, sep : list(map(sep.join, zip(*([iter(map(str, lst))]*(len(lst))))))[0]
>>> from math import pi
>>> st = [1, 2, 3, 4, 'stringa', 6, 7.89, pi]
>>> stp = strcat(st, '\n')
>>> print(stp)
1
2
3
4
stringa
6
7.89
3.141592653589793
>>>
OK. Ci sono 2 condizioni da considerare.
1. La lista contiene sub-liste probabilmente non si ottiene quello sperato:
>>> st = [1, 2, [3, 4], 5, 6]
>>> strcat(st, ' ')
'1 2 [3, 4] 5 6'
>>>
Rendere flat la lista è semplicissimo con altri linguaggi (qualcuno ha detto Racket?) ma per quanto ho visto non facile con Python; su Stack Overflow ho trovato codici per casi semplici ma nessuno tratta il caso generale di liste con liste annidate su più livelli.
Però, ripensandoci, non è una condizione pratica. È come la volpe che scoprì che l'uva non era matura.
2. La lista contiene numeri floating-point (come pi nell'esempio). Devo gestire il formato. Ecco, si può fare
🔴
Nessun commento:
Posta un commento