[python] Prevod stringu na seznam integeru a zpatky

Petr Prikryl PrikrylP na skil.cz
Čtvrtek Září 6 15:55:27 CEST 2007


Leos Pol
> Ne, ze bych se pokladal za zkusenyho Pythonyra,
> ale tady je muj kousek kodu, jak bych to napsal ja:
> 
>     s = '1, 2, 3, 4, 5, 6, 7, 8, 9'
>     l = eval(s)
>     s = ', '.join(map(str, l))

Skromnost stranou ;) Ale je tam jedna drobnost.
Když už, nepoužil bych identifikátor l. Jednak
v některých fontech vypadá jako jednička a jednak
je výsledkem tuple:

s = '1, 2, 3, 4, 5, 6, 7, 8, 9'
t = eval(s)
print repr(t)
s = ', '.join(map(str, t))
print repr(s)

... vyprodukuje

c:\tmp>python a.py
(1, 2, 3, 4, 5, 6, 7, 8, 9)
'1, 2, 3, 4, 5, 6, 7, 8, 9'

To znamená, že to zpracování by mohlo
z t jen číst.

To původní řešení bych mírňoučce upravil
tím, že bych v join() vynechal hranaté závorky.
Bude se to chápat jako generátorový výraz 
a produkované prvky se zpracují "za letu",
bez vytváření dočasného seznamu:

lst = [int(m) for m in s.split(',')]
print repr(lst)
# processing
s = ', '.join(str(n) for n in lst)
print repr(s)

Pokud by ona fáze "processing" postupně 
zpracovávala jednotlivé prvky, pak by se
alternativně dalo vyhnout konstruování 
toho lst seznamu před zpracováním a produkoval
by se naopak seznam výsledků, který by se 
spojil do řetězce:

lst = []
for m in s.split(','):
    lst.append(int(m) * 2)
s = ', '.join(str(n) for n in lst)
print repr(s)

Při takovém charakteru zpracování pak
lze psát taky:

def mujGenerator(s):
    for m in s.split(','):
        yield str(int(m) * 2)

s = ', '.join(mujGenerator(s))
print repr(s)

Milovníci funkcionálního přístupu mají
cyklus for zakuklený i ve funkci map(), takže
se dá napsat:

s = ', '.join(map(lambda m: str(int(m) *2), s.split(',')))
print repr(s)

Ale asi to není v Pythonu zrovna nejefektivnější
způsob.

pepr








Další informace o konferenci Python