2017-07-28 4 views
-1

Ich habe eine Reihe von Funktionen, die am Ende eine Liste geben, wobei das erste Element eine Zahl enthält, die von den Wörterbüchern abgeleitet ist, und das zweite und dritte Element Wörterbücher sind.Speichern von zufällig generierten Wörterbüchern in Python

Diese Wörterbücher wurden zuvor zufällig generiert.

Die von mir verwendete Funktion erzeugt eine bestimmte Anzahl dieser Wörterbücher, wobei versucht wird, die höchstmögliche Anzahl als erstes Element zu erhalten. (Es wurde entwickelt, um Würfelröllchen zu optimieren).

Das alles funktioniert gut, und ich kann den Wert des höchsten ersten Elements aus allen Iterationen drucken. Wenn ich jedoch versuche, die beiden Wörterbücher, die mit dieser ersten Nummer verbunden sind, zu drucken (wobei zu beachten ist, dass sie alle in einer Liste enthalten sind), erzeugt sie scheinbar zufällig die beiden anderen Wörterbücher.

def repeat(type, times): 
    best = 0 
    for i in range(0, times): 
     x = rollForCharacter(type) 
     if x[0] > best: 
      print("BEST:", x) 
      best = x[0] 

    print("The highest average success is", best) 

    return best 

Das funktioniert gut. Das letzte, was gezeigt ist:

BEST: (3.58, [{'strength': 4, 'intelligence': 1, 'charisma': 1, 'stamina': 4, 'willpower': 2, 'dexterity': 2, 'wits': 5, 'luck': 2}, {'agility': 1, 'brawl': 2, 'investigation': 3, 'larceny': 0, 'melee': 1, 'survival': 0, 'alchemy': 3, 'archery': 0, 'crafting': 0, 'drive': 1, 'magic': 0, 'medicine': 0, 'commercial': 0, 'esteem': 5, 'instruction': 2, 'intimidation': 2, 'persuasion': 0, 'seduction': 0}]) The highest average success is 3.58

Aber wenn ich etwas versuchen, die Liste zu speichern, die diese Nummer gab:

def repeat(type, times): 
    best = 0 
    bestChar = [] 
    for i in range(0, times): 
     x = rollForCharacter(type) 
     if x[0] > best: 
      print("BEST:", x) 
      best = x[0] 
      bestChar = x 

    print("The highest average success is", best) 
    print("Therefore the best character is", bestChar) 

    return best, bestChar 

ich dies als das letzte Ergebnis, das ist in Ordnung:

BEST: (4.15, [{'strength': 2, 'intelligence': 3, 'charisma': 4, 'stamina': 4, 'willpower': 1, 'dexterity': 2, 'wits': 4, 'luck': 1}, {'agility': 1, 'brawl': 0, 'investigation': 5, 'larceny': 0, 'melee': 0, 'survival': 0, 'alchemy': 7, 'archery': 0, 'crafting': 0, 'drive': 0, 'magic': 0, 'medicine': 0, 'commercial': 1, 'esteem': 0, 'instruction': 3, 'intimidation': 0, 'persuasion': 0, 'seduction': 0}]) The highest average success is 4.15

aber die letzte Zeile ist

Therefore the best character is (4.15, [{'strength': 1, 'intelligence': 3, 'charisma': 4, 'stamina': 4, 'willpower': 1, 'dexterity': 2, 'wits': 2, 'luck': 3}, {'agility': 1, 'brawl': 0, 'investigation': 1, 'larceny': 4, 'melee': 2, 'survival': 0, 'alchemy': 2, 'archery': 4, 'crafting': 0, 'drive': 0, 'magic': 0, 'medicine': 0, 'commercial': 1, 'esteem': 0, 'instruction': 0, 'intimidation': 2, 'persuasion': 1, 'seduction': 0}])

Wie Sie sehen, stimmt das nicht mit dem, was ich will, und was direkt darüber gedruckt wird.

Durch ein wenig Überprüfung, realisierte ich, was es ausgibt, da der "Beste Charakter" nur der Letzte ist, der generiert wird, der nicht der Beste ist, nur der Letzte. Es ist jedoch nicht so einfach, weil das erste Element das höchste Ergebnis ist, das aufgezeichnet wurde, nur nicht von dem Zeichen im Rest der Liste. Das ist wirklich verwirrend, weil es bedeutet, dass die Liste irgendwie bearbeitet wird, aber zu keinem Zeitpunkt kann ich sehen, wo das passieren würde.

Mache ich etwas dummes, wobei der Charakter jedes Mal zufällig generiert wird? Ich würde nicht so denken, da x[0] das korrekte Ergebnis gibt und gut gespeichert wird, also was ändert sich, wenn es die ganze Liste ist?

Von der Funktion rollForCharacter() gibt rollResult, character zurück, das ist nur die Nummer und dann die zwei Wörterbücher.

Ich würde es sehr schätzen, wenn jemand herausfinden und erklären könnte, wo ich falsch liege und warum es die richtige Antwort auf die Konsole drucken kann, aber nicht richtig speichern Sie eine Zeile unten!

EDIT:

Dictionary 1 Code:

attributes = {} 


def assignRow(row, p): # p is the number of points you have to assign to each row 
    rowValues = {} 
    for i in range(0, len(row)-1): 
     val = randint(0, p) 
     rowValues[row[i]] = val + 1 
     p -= val 
    rowValues[row[-1]] = p + 1 
    return attributes.update(rowValues) 


def getPoints(): 
    points = [7, 5, 3] 
    shuffle(points) 
    row1 = ['strength', 'intelligence', 'charisma'] 
    row2 = ['stamina', 'willpower'] 
    row3 = ['dexterity', 'wits', 'luck'] 
    for i in range(0, len(points)): 
     row = eval("row" + str(i+1)) 
     assignRow(row, points[i]) 

Wörterbuch 2 Code:

skills = {} 


def assignRow(row, p): # p is the number of points you have to assign to each row 
    rowValues = {} 
    for i in range(0, len(row) - 1): 
     val = randint(0, p) 
     rowValues[row[i]] = val 
     p -= val 
    rowValues[row[-1]] = p 
    return skills.update(rowValues) 


def getPoints(): 
    points = [11, 7, 4] 
    shuffle(points) 
    row1 = ['agility', 'brawl', 'investigation', 'larceny', 'melee', 'survival'] 
    row2 = ['alchemy', 'archery', 'crafting', 'drive', 'magic', 'medicine'] 
    row3 = ['commercial', 'esteem', 'instruction', 'intimidation', 'persuasion', 'seduction'] 
    for i in range(0, len(points)): 
     row = eval("row" + str(i + 1)) 
     assignRow(row, points[i]) 
+0

Können Sie den Code posten, den Sie zum Generieren der Wörterbücher verwenden? – perigon

Antwort

1

Es ist wie das Wörterbuch sieht wird neu erzeugt, die sich leicht, wenn das passieren könnte, Die Funktion rollForCharacter gibt entweder einen Generator zurück oder überschreibt eine globale Variable, die von einem nachfolgenden Zyklus der Schleife überschrieben wird.

Ein einfacher, aber hacky Weg, um das Problem zu lösen, zum Zeitpunkt der Speicherung, eine tiefe Kopie des Wörterbuchs zu nehmen wäre, so dass Sie sicher sind, sind Sie an diesem Punkt die Werte halten:

def repeat(type, times): 
    best = 0 
    bestChar = [] 
    for i in range(0, times): 
     x = rollForCharacter(type) 
     if x[0] > best: 
      print("BEST:", x) 
      best = x[0] 
      # Create a brand new tuple, containing a copy of the current dict 
      bestChar = (x[0], x[1].copy()) 

Die richtige Antwort wäre jedoch, eine eindeutige Wörterbuchvariable zu übergeben, die vom späteren Code nicht betroffen ist.

Siehe this SO answer mit ein wenig mehr Kontext darüber, wie das Übergeben einer Referenz an ein Wörterbuch riskant sein kann, da es immer noch ein veränderbares Objekt ist.

+0

Danke für den Link, der wirklich geholfen hat. Es stellt sich heraus, ich brauche deepcopy(), aber das funktioniert super danke! –

Verwandte Themen