[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