[python] Modifikace seznamu bez kopirovnani (bylo SQLite - forma selectovaných dat)

superman feed na centrum.cz
Pondělí Leden 8 09:27:30 CET 2007


> Iterace není "read only". Read only jsou zpřístupňované objekty.

Iterace je "read only" vzhledem k iterovanému objektu, což je občas dost 
nešikovné.

> Od Python 2.3 existuje standardní funkce enumerate(), která
> vrací iterátor. Jeho metoda next() vrací dvojici (index, element).
> Takže původní kód
> 
>   a = [(1,2),(3,4)]
>   for i in range(len(a)):
>       a[i] = list(a[i])
> 
> Můžu přepsat na 
> 
>   a = [ (1, 2), (3, 4) ]
>   for i, elem in enumerate(a):
>       a[i] = list(elem)

Obávám se, ale že ten můj kód, tedy první verze bude rychlejší.

Jasně je druhou otázkou zda jde o high level konstrukce, nebo o rychlost.

> Tohle je problém v rozdílném pojetí homogenního pole
> (všechny prvky mají stejný typ) a pythonovského
> seznamu, který je svým způsobem sice taky homogenní,
> ale obsahuje jen reference, které se automaticky 
> dereferencují (když už musím použít tak pěkně české slovo).

Ano tohle je pro mě vždycky problém přepnout do myšlení dynamických 
jazyků, kde neexistují hodnoty, ale jen odkazy.

> V Pythonu nemohu měnit hodnotu prvku typu int, protože
> jde o objekt s konstantní hodnotou (immutable). Mohu jej
> pouze nahradit jiným objektem typu int, který je vypočtený
> z hodnoty původního a z další konstanty. V seznamu tedy
> musím opět použít obrat, kdy modifikuji samotný prvek 
> seznamu. V tomto případě ale dojde k modifikaci každého
> prvku seznamu, takže nejefektivnější a nejstručnější 
> způsob spočívá v konstrukci nového, upraveného seznamu:
> 
>   a = [ 1, 2, 3, 4, 5 ]
>   a = [ e+3 for e in a ]
>   print a

V mém případě se ale nový seznam nekonstruoval, nedocházelo tedy k 
alokaci nového objektu. Navíc hodnoty typu int se nutně nemusejí znovu 
vytvářet, protože vnitřně je Python intepretr udělaný tak, že základní 
řada čísel je "předalokovaná" při startu interpretru a při použití 
běžných konstant se prostě jen předhodí odkaz na již uvnitř Python 
interpreteru existující objekt typu int. Kdyby se všechno mělo alokovat 
a znovu vytvářet, tak je Python slimák.

> Pokud bych definoval svou vlastní třídu objektů 
> s celočíselnou hodnotou, které by mohly být modifikovány
> (mutable), bylo by možné modifikovat seznam bez
> vytváření nového.

To jenom se snaží obejít "read only" vlastnost iterátoru. Jinak já jsem 
modifikoval seznam bez vytváření nového.

Ing. Miloslav Ponkrác


Další informace o konferenci Python