Python Liste mit Zahlen Mutieren/Verändern?

1 Antwort

Sorry, aber ich verstehe noch nicht ganz, was du mit „zufällig mutieren“ meinst. Was soll die neue Liste mit der alten zu tun haben?

Bei deinem Beispiel haben sich 3 der Einträge verändert (ein Eintrag hat um 1 zugenommen, ein Eintrag hat um 1 abgenommen, ein Eintrag hat um 2 zugenommen), und 3 Einträge sind gleich geblieben. Sollen die Einträge zufällig durch Addition/Subtraktion verändert werden? Wenn ja in welchem Ausmaß? Gibt es da eine maximale Abweichung oder sonstige Bedingungen. Sonst könnte danach ja beispielsweise die Liste auch so aussehen: [-10, 4, 1245, 138, 1, 5], oder?

======Ergänzung======

Möchtest du beispielsweise sowas in der Art...?

from random import randint
def mutate(L, d):
    # Ändert die Einträge der Liste L jeweils zufällig ab, so dass die
    # Differenz der Einträge zu den entsprechenden Eintrag in der vorigen
    # Version der Liste maximal d beträgt.
    L[:] = [k + randint(-d, d) for k in L]
    return(None)


L = [1, 4, 65, 2, 21, 16]
print(L)
mutate(L, 3)
print(L)

Oder so...

from random import randint
def mutate(L, d):
    # Ändert die Einträge der Liste L jeweils zufällig ab, so dass die
    # Differenz der Einträge zu den entsprechenden Eintrag in der vorigen
    # Version der Liste maximal d beträgt.
    for i, k in enumerate(L):
        L[i] = k + randint(-d, d)
    return(None)

L = [1, 4, 65, 2, 21, 16]
print(L)
mutate(L, 3)
print(L)

Das habe ich extra so geschrieben, dass die Liste L direkt verändert wird, da du etwas von „zufällig mutieren“ geschrieben hast. Je nach Szenario, in dem du das nutzen möchtest, könnte es evtl. sinnvoller sein, nicht die Liste „in place“ zu verändern, sondern die neue Liste zu erzeugen und dann später außerhalb der Funktion die Liste zu ersetzen. (Das vermeidet eher böse Überraschungen, die sonst leichter passieren, wenn man nicht aufpasst.) Also beispielsweise so...

from random import randint
def zufallsliste(L, d):
    # Liefert eine Liste die entsteht, wenn man die Einträge der Liste L
    # jeweils zufällig abändert, wobei die Differenz der Einträge zu den
    # entsprechenden Einträgen der Liste L jeweils maximal d beträgt.
    return([k + randint(-d, d) for k in L])

L = [1, 4, 65, 2, 21, 16]
print(L)
L = zufallsliste(L, 3)
print(L)
kaceye3003  30.09.2022, 18:06

Eine Frage zu deinem 1. Code: Warum sind bei der Zuweisung von L die eckigen Klammern notwendig?

L[:] =

Warum nicht einfach L =?

0
mihisu  30.09.2022, 19:25
@kaceye3003

Wenn man nur „L =“ statt „L[:] =“ verwendet, würde nicht die globale Liste außerhalb der Funktion verändert werden, sondern es würde innerhalb des Funktionsaufrufs eine neue lokale Liste L erstellt werden. Die lokale Liste wäre dann nach Verlassen des Funktionsaufrufs nicht mehr verfügbar, sodass man danach dann außerhalb der Funktion weiterhin die vorige (unveränderte) Liste L hätte.

Bei „L[:] =“ wird tatsächlich die Liste L an ihrem Platz verändert, statt das einer neuen (lokalen) Variable L zuzuweisen.

Etwas einfacheres Beispiel (ohne den zufälligen Kram)...

def funktion_macht_irgendwas():
    L = [4, 5]
    print("Liste L (noch im Funktionsaufruf): ", L)

L = [1, 2, 3]
print("Liste L (vor Funktionsaufruf):", L)
funktion_macht_irgendwas()
print("Liste L (nach Funktionsaufruf):", L)

Vergleiche davon die Ausgabe mit der Ausgabe von...

def funktion_macht_irgendwas():
    L[:] = [4, 5]
    print("Liste L (noch im Funktionsaufruf): ", L)

L = [1, 2, 3]
print("Liste L (vor Funktionsaufruf):", L)
funktion_macht_irgendwas()
print("Liste L (nach Funktionsaufruf):", L)

Das „Problem“ könnte man natürlich auch anderweitig umgehen, indem man zu Beginn der Funktion ein „global L“ schreibt.

1
kaceye3003  30.09.2022, 19:27
@mihisu

Danke! Funktioniert das für jede Art von Variablen oder nur bei Listen?

0
mihisu  30.09.2022, 19:42
@kaceye3003

Das mit „L[:]“ funktioniert nicht bei jeder Art von Variablen. Bei einer Ganzzahl (int) würdest du beispielsweise die Fehlermeldung...

TypeError: 'int' object does not support item assignment

... erhalten, da für eine Ganzzahl L der Ausdruck „L[:]“ keinen Sinn ergibt. Ganzzahlen sind im Gegensatz zu Listen übrigens auch keine sogenannten „mutable objects“ (veränderliche Objekte).

Aber auch hier tritt ein entsprechender Effekt mit lokalen Variablen auf. Beispiel...

def funktion_tut_etwas():
    i = 2
    print(i)

i = 1
print(i)
funktion_tut_etwas()
print(i)

Aber auch hier könnte man das mit „global i“ lösen, wenn man unbedingt möchte...

def funktion_tut_etwas():
    global i
    i = 2
    print(i)

i = 1
print(i)
funktion_tut_etwas()
print(i)

Mit „global i“ sagt man Python, dass die globale Variable i statt einer lokalen Variable i verwendet werden soll.

1
ComUmfragen 
Fragesteller
 01.10.2022, 12:42

Danke für deine ausführliche antwort. Ich hätte vielleicht etwas mehr kontext geben sollen. Ich möchte durch evolution eine optimierte lösung für ein problem finden. AKA evolutionary algorithm. Meine Lösungsmöglichkeiten werden umgewandelt in eine liste von zahlen. für die jeweils nächste generation möchte ich die bisher besten Lösungsmöglichkeiten also etwas modifizieren. Also aus einer liste aus zahlen, etwa 10 ähnliche, leicht mutierte listen machen, um sich so an die optimale lösung ranzutasten. Ich hatte einen ziemlich unoptimierten code dafür, und wollte deshalb nur nach schlaueren kompakteren lösungen suchen...

0
ComUmfragen 
Fragesteller
 01.10.2022, 13:20

Ich bin jetzt dank deiner antwort auf diese lösung gekommen:


def mutate_list(input_list):
        mutated_list = [k + round(random.uniform(-(k*0.2), (k*0.2)), 3) if neoneural.chance(60) else k for k in input_list]
        return mutated_list
    def mutate_network(input_network):
        for layer in input_network:
            input_network[layer]["weights"]=[neoneural.mutate_list(k) for k in input_network[layer]["weights"]]
            input_network[layer]["biases"]=[neoneural.mutate_list(k) for k in input_network[layer]["biases"]]
        return input_network
1