python: hatékony adatkezelés

A feladat nem túl bonyolult, de nem tudom, hogy lenne a leghatékonyabb:

Van sok (pár száz ezer lehet) objektumom, amiket el akarok tárolni a memóriában.
Menet közben van, hogy egyet-egyet ki akarok törölni. Újat akarok hozzáadni persze, jó a végére (mindegy, hova).
Akarok olyasmit, hogy egy ciklus végig tudjon menni az összesen.
Akarok olyasmit, hogy az objektum egy kiválasztott attribútuma alapján rendezve tudjak végigmenni rajtuk.
Akarok szűrni egy adott attribútumra.

C++-ban kb. tudom, hogy állnék neki. Az objektumokat felfűzném egy kétirányú láncolt listára, azon jól végig lehet menni egy iterátorral, és lehet belőle törölni.

A rendezéseket, szűréseket egy másik index tárolóval csinálnám, gondolom vector-ral. Szépen pointereket tárolnék el benne ugye az adott objektumra.

Nade hogy csinálom meg ugyanezt python-ban?

Legyen list, és az pop( i ) az elem törlése?
Az index egy másik lista, ami a sorszámokat tárolja?

Hogy határozom meg egy objektum értékét? Úgy értem, pl. melyik beépített python függvénnyel tudom kiíratni, illetve van-e olyan speciális tagfüggvény, ami az objektum értékét adja vissza az ilyen ellenőrzések számára?

Tudok esetleg valahogy olyasmit írni, hogy mylist.index( 'foo'), és az objektumom valamelyik tagfüggvénye adja vissza a stringet?

A sort minek alapján rendez? Az objektum értéke alapján?

Tudok olyan függvényt készíteni, ami az objektum egy másik értékét adja vissza?

Tehát mondjuk foo szerint rendezek sorba, de bar szerint szűrök.

G

Hozzászólások

Először próbálkozz egy egyszerű list ( [] )-tel. Ehhez lehet fűzni, rendezni, törölni belőle...

Rendezésre a sort() vagy ha függvényekben, iterátorokban (generátorokban) gondolkodsz, akkor a sorted() fv. a barátod:


for elt in sorted(alist, keys=lambda z: z.foo):
  if z.bar != '2': continue
  ...

Ha tetszik a "functional programming" (a la Haskell/Lisp/Scheme), akkor nézd meg az

itertools

modult!


import itertools
for elt in itertools.ifilter(lambda z: z.bar == '2', sorted(alist, keys=lambda z: z.foo)):
  ...

Én először megcsinálnám egyszerűen list-tel, aztán az optimalizálás már timeit/profile segítségével egyszerű.

De ha SOK elemet tárolsz (memória probléma), akkor az

anydbm

,

shelve

lehetnek a te barátaid.

Más: nem pointereket/elem sorszámokat kell tárolnod az index listákban (ami már az optimalizálás kategória!), hanem magukat az elemeket - ha Python objektum (csak a legelemibbekre (szám, string) nem lesz ez igaz), akkor a Python amúgy is csak a pointert rakja a listába, nem az egész objektum újabb példányát - így a hivatkozás is egyszerű (csak a törlés nem :) ).

Minden objektumnak lehet egy __cmp__ függvénye, ami megmondja a rendezést.

Ha van még kérdésed, szívesen válaszolok (szeretem a Pythont :) )

GT

Amennyit megnéztem most, az egész jó.
Megtaláltam az operátor overload-ot :-)
Így most már tudok rendezni.

Működik az index() is.

A filter() se rossz igazán, csak nem jöttem rá, lehet-e paraméteres szűrőfüggvényt írni.
Mert azért az hülyesének látszik, hogy egy változó teljes lehetséges értékkészletére külön-külön függvény készüljön. :-)

Vagy az lenne jó, ha menet közben lehetne létrehozni, pl.
filter( def f(x): return x.d == 42, myList)
vagy valami módon átdobni neki paramétert, hogy mivel is kellene összehasonlítania.

Vagy filter helyett mást használok :-)

Köszi,
G

"Vagy az lenne jó, ha menet közben lehetne létrehozni"

Minden menet közben jön létre, mindent felülírhatsz gyakorlatilag bármikor.
Minden név csak egy referencia, menet közben bármit betehetsz mögé és megváltoztathatsz. Persze óvatosan.

Konkrétan amire Te kérdeztél rá, arra szintaxis:


regilista = [a, b, c]
def szurofuggveny(listaelem):
    return True
ujlista = [ujlistaelem for regilistaelem in regilista if szurofuggveny(regilistaelem)]

Egyébként a filter() régi stílusú, és helyette újabban a fenti formátumot részesítik előnyben.