function - Storing randomly generated dictionaries in Python -


i have series of functions end giving list, first item containing number, derived dictionaries, , second , third items dictionaries.

these dictionaries have been randomly generated.

the function using generates given number of these dictionaries, trying highest number possible first item. (it's designed optimise dice rolls).

this works fine, , can print value of highest first item iterations. however, when try , print 2 dictionaries associated first number (bearing in mind they're in list together), seemingly randomly generates 2 other dictionaries.

def repeat(type, times):     best = 0     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 

this works great. last thing shown is:

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}]) highest average success 3.58

but if try store list gave number:

def repeat(type, times):     best = 0     bestchar = []     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 best character is", bestchar)      return best, bestchar 

i last result, fine:

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}]) highest average success 4.15

but last line is

therefore best character (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}])

as can see doesn't match want, , printed literally right above it.

through little bit of checking, realised gives out "best character" last 1 generated, not best, recent. however, isn't simple, because first element highest result recorded, not character in rest of list. confusing because means list somehow being edited @ no point can see happen.

am doing stupid whereby character randomly generated every time? wouldn't think since x[0] gives correct result , stored fine, changes when it's whole list?

from function rollforcharacter() returns rollresult, character number , 2 dictionaries.

i appreciate if figure out , explain i'm going wrong , why can print correct answer console yet not store correctly line below!

edit:

dictionary 1 code:

attributes = {}   def assignrow(row, p): # p number of points have assign each row     rowvalues = {}     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']     in range(0, len(points)):         row = eval("row" + str(i+1))         assignrow(row, points[i]) 

dictionary 2 code:

skills = {}   def assignrow(row, p):  # p number of points have assign each row     rowvalues = {}     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']     in range(0, len(points)):         row = eval("row" + str(i + 1))         assignrow(row, points[i]) 

it dictionary being re-generated, happen if function rollforcharacter returns either generator or alternatively overwriting global variable being overwritten subsequent cycle of loop.

a simple-but-hacky way solve problem take deep copy of dictionary @ time of storing, you're sure you're keeping values @ point:

def repeat(type, times):     best = 0     bestchar = []     in range(0, times):         x = rollforcharacter(type)         if x[0] > best:             print("best:", x)             best = x[0]             # create brand new tuple, containing copy of current dict             bestchar = (x[0], x[1].copy()) 

the correct answer pass unique dictionary variable not affected later code.

see this answer bit more context how passing reference dictionary can risky it's still mutable object.


Comments

Popular posts from this blog

php - Vagrant up error - Uncaught Reflection Exception: Class DOMDocument does not exist -

vue.js - Create hooks for automated testing -

Add new key value to json node in java -