在Python

时间:2017-07-28 08:34:19

标签: python function dictionary

我有一系列函数最终会给出一个列表,第一个项目包含一个从字典派生的数字,第二个和第三个项目是字典。

这些词典以前是随机生成的。

我正在使用的函数会生成给定数量的这些词典,尝试将最高数量作为第一项。 (它旨在优化骰子卷)。

这一切都很好,我可以打印所有迭代中最高的第一项的值。但是,当我尝试打印与第一个数字相关的两个词典时(记住它们都在一起列表中),它似乎随机生成了另外两个词典。

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

这很有效。最后显示的是:

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

但是,如果我尝试一些东西来存储给出这个数字的列表:

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

我得到这个作为最后的结果,这很好:

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

但最后一行是

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}])

正如你所看到的,这与我想要的东西不符,字面意思就在它上面。

通过一点点检查,我意识到它给出了什么,因为“最佳角色”只是生成的最后一个,这不是最好的,只是最近的。但是,它并不那么简单,因为第一个元素是记录的最高结果,而不是来自列表其余部分的字符。这真的令人困惑,因为它意味着列表以某种方式被编辑,但在任何时候我都无法看到它会发生在哪里。

我是否做了一些愚蠢的事情,每次都会随机生成角色?我不这么认为,因为x[0]给出了正确的结果并且存储得很好,所以当它是整个列表时会发生什么变化?

从函数rollForCharacter()返回rollResult, character,这只是数字,然后是两个词典。

如果有人能弄清楚并解释我出错的地方以及为什么它可以打印正确的答案而不是将其正确存储在下面一行,我将不胜感激!

编辑:

词典1代码:

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])

字典2代码:

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])

1 个答案:

答案 0 :(得分:1)

看起来字典正在重新生成,如果函数rollForCharacter返回生成器或者覆盖正被循环的后续循环覆盖的全局变量,则很容易发生。

解决问题的一种简单而又简单的方法是在存储时对字典进行深层复制,这样您就可以确定在这一点上保留了值:

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())

然而,正确的答案是传递一个不受以后代码影响的唯一字典变量。

请参阅this SO answer,了解更多关于如何将引用传递到字典的风险,因为它仍然是一个可变对象。