Seite 1 von 1

Zugriff by reference auf verschachtelte Liste

Verfasst: Sonntag 6. Februar 2011, 20:20
von Gerenuk
Oh, bin gerade fleißig beim programmieren und hoffe jemand findet folgende Frage interessant :)

Ich wollte mir ein normalize programmieren, dass folgendes macht

Code: Alles auswählen

def normalize(l, aggregate=sum, norm_by=operator.truediv):
   aggregated=aggregate(l)
   for i in range(len(l)):
       l[i]=norm_by(l[i], aggregated)
Nun ist es aber komplizierter, wenn ich verschachtelte Liste habe wie a[x][y] und eigentlich über x normalisieren will. Also effektiv

Code: Alles auswählen

aggregated=sum(a[i]["const"] for i in range(len(a)))
for i in range(len(a)):
  a[i]["const"]/=aggregated
Ich vermute fast irgendwas mit gettern und settern und so Tricks könnte das Problem lösen. Bloß so auf Anhieb fällt mir da nix ein :(
Ideen?

Re: Zugriff by reference auf verschachtelte Liste

Verfasst: Sonntag 6. Februar 2011, 20:43
von Darii
Ja und was ist jetzt dein Problem?

Re: Zugriff by reference auf verschachtelte Liste

Verfasst: Sonntag 6. Februar 2011, 20:49
von Gerenuk
Na ich kann schreiben

Code: Alles auswählen

l=[1,2,3,4]
normalize(l)
Aber was mache ich wenn

Code: Alles auswählen

l=[[1,0],[2,0],[3,0],[4,0]]
und ich will l[x][0] mit einer externen function über x normalisieren? Also dass ich normalize irgendwie auf l anwende, so dass l=[[0.1,0],[0.2,0],[0.3,0],[0.4,0]] rauskommt.

Da fällt mir keine clevere Lösung ein...

Re: Zugriff by reference auf verschachtelte Liste

Verfasst: Sonntag 6. Februar 2011, 21:08
von Gerenuk
Hmm, also genial wäre ja

Code: Alles auswählen

normalize(l[...][0])
Bloß kann man das mit Python so zusammenhacken? Klingt anspruchsvoll...

Re: Zugriff by reference auf verschachtelte Liste

Verfasst: Sonntag 6. Februar 2011, 21:27
von BlackJack
@Gerenuk: Ich finde die API für Python-Verhältnisse etwas ungewöhnlich. Das ``for i in range(len(l)):`` ist ein Wink mit dem Zaunpfahl, dass das nicht wirklich "pythonisch" ist. In der Regel erzeugt man in Python in solchen Fällen eine neue Liste und verändert nicht die Alte.

Ansonsten könnte `numpy` hier wahrscheinlich eine Lösung sein, denn dort kann man solche "slices" sicher machen.

Re: Zugriff by reference auf verschachtelte Liste

Verfasst: Sonntag 6. Februar 2011, 21:33
von BlackJack
Mit `numpy`:

Code: Alles auswählen

In [100]: a = np.array([[1, 0], [2, 0], [3, 0], [4, 0]], float)

In [101]: b = a[...,0]

In [102]: b /= b.sum()

In [103]: a
Out[103]: 
array([[ 0.1,  0. ],
       [ 0.2,  0. ],
       [ 0.3,  0. ],
       [ 0.4,  0. ]])

Re: Zugriff by reference auf verschachtelte Liste

Verfasst: Sonntag 6. Februar 2011, 21:37
von Gerenuk
@BlackJack:
Naja, pythonisch ist was am Ende cool ist :)
Und manchmal möchte man halt in-place bearbeiten.

Also numpy ist ja krass. Sowas in der Art müsste ich für lists und dicts nachprogrammieren :) Jemand eine Ahnung wie das ungefähr geht?

Re: Zugriff by reference auf verschachtelte Liste

Verfasst: Sonntag 6. Februar 2011, 21:45
von cofi
Gerenuk hat geschrieben:@BlackJack:
Naja, pythonisch ist was am Ende cool ist :)
Dem muss ich widersprechen. Pythonisch ist, was dem Zen von Python folgt. Also mal `import this` lesen.
Gerenuk hat geschrieben:Und manchmal möchte man halt in-place bearbeiten.
Da empfiehlt sich `enumerate`.
Gerenuk hat geschrieben:Also numpy ist ja krass. Sowas in der Art müsste ich für lists und dicts nachprogrammieren :) Jemand eine Ahnung wie das ungefähr geht?
Also ich wuerde da ja mal bei numpy schaun ..

Re: Zugriff by reference auf verschachtelte Liste

Verfasst: Montag 7. Februar 2011, 22:41
von Gerenuk
cofi hat geschrieben: Dem muss ich widersprechen. Pythonisch ist, was dem Zen von Python folgt. Also mal `import this` lesen.
In Python kann man Listen nicht anders als mit "for i in range(len(l))" bearbeiten, wenn es per Referenz sein soll. Das ist also sehr wohl pythonisch und ist in allen Beispielsammlungen.

Naja, ich hatte noch ne super Idee was ich implementieren werde. Ich mache mir eine Klasse
Miter(d, "key1", ..., "key2", ..., 1, "key3")
und schreibe dazu getitem, setitem und iter so dass sich das ganze verhält wie ein dict a[x,y] <-> d["key1"][x]["key2"][y][1]["key3"] :)

Das ist mal richtig pythonisch und erlaubt sehr dynamische Programmierung. An normalize muss ich dafür nichts mehr ändern und sämtlich Funktionen die nichts anderes als einfache dicts kennen, werden damit umgehen können :)

OK, numpy gab dir Idee vor ;)

Re: Zugriff by reference auf verschachtelte Liste

Verfasst: Montag 7. Februar 2011, 23:01
von cofi
Gerenuk hat geschrieben:
cofi hat geschrieben:Dem muss ich widersprechen. Pythonisch ist, was dem Zen von Python folgt. Also mal `import this` lesen.
In Python kann man Listen nicht anders als mit "for i in range(len(l))" bearbeiten, wenn es per Referenz sein soll. Das ist also sehr wohl pythonisch und ist in allen Beispielsammlungen.
Das Bezog sich in erster Linie auf deine Definition von "pythonisch". Aber wenn das nicht anders geht, dann ist folgender Code wohl nicht lauffähig:

Code: Alles auswählen

def normalize(l, aggregate=sum, norm_by=operator.truediv):
   aggregated = aggregate(l)
   for i, e in enumerate(l):
       l[i] = norm_by(e, aggregated)

Re: Zugriff by reference auf verschachtelte Liste

Verfasst: Montag 7. Februar 2011, 23:05
von EyDu
Gerenuk hat geschrieben:
cofi hat geschrieben: Dem muss ich widersprechen. Pythonisch ist, was dem Zen von Python folgt. Also mal `import this` lesen.
In Python kann man Listen nicht anders als mit "for i in range(len(l))" bearbeiten, wenn es per Referenz sein soll. Das ist also sehr wohl pythonisch und ist in allen Beispielsammlungen.
Den Hinweis zu enumerate hast du aber schon gelesen, oder?
Gerenuk hat geschrieben:Naja, ich hatte noch ne super Idee was ich implementieren werde. Ich mache mir eine Klasse
Miter(d, "key1", ..., "key2", ..., 1, "key3")
und schreibe dazu getitem, setitem und iter so dass sich das ganze verhält wie ein dict a[x,y] <-> d["key1"][x]["key2"][y][1]["key3"] :)[/code]
Was immer du vor hast, wenn du Dictniaries so verschachtelt aufbaust, dann machst du mit Sicherheit etwas falsch. Wahrscheinlich möchtest du Klassen und mehr Funktionen benutzen.[/code]
Gerenuk hat geschrieben:Das ist mal richtig pythonisch und erlaubt sehr dynamische Programmierung. An normalize muss ich dafür nichts mehr ändern und sämtlich Funktionen die nichts anderes als einfache dicts kennen, werden damit umgehen können :)[/code]
Wo ist so eine Struktur denn übersichtlich? Dynamische Programmierung ist übrigens nicht das, was du glaubt was es ist ;-)

OK, numpy gab dir Idee vor ;)

Re: Zugriff by reference auf verschachtelte Liste

Verfasst: Montag 7. Februar 2011, 23:32
von Leonidas
Gerenuk hat geschrieben:In Python kann man Listen nicht anders als mit "for i in range(len(l))" bearbeiten, wenn es per Referenz sein soll. Das ist also sehr wohl pythonisch und ist in allen Beispielsammlungen.
Also ganz oft ist in Python das Zurückgeben von veränderten Listen pythonischer als das ändern ebendieser. Aber das nur nebenbei.