如何在Python中舍入到特定值

如何在Python中舍入到特定值,python,function,rounding,Python,Function,Rounding,我正在研究一种自动为角色扮演游戏创建角色表的算法。在游戏中,你有一些属性,你可以在这些属性中添加点数来增加点数。但是,在某个值上,实际属性的值增加1需要2个点。从具有一定数量的点开始,默认情况下,每个属性的值为1 我有一个随机分配点的程序,但是我被困在如何在必要时将这些值(在字典中)更改为四舍五入 例如,如果我在“强度”中加3分,这很好,我得到的“强度”值为3(包括基数1)。然而,如果我加上4点,我仍然应该只有4的值。需要5个点(加上基数1)才能得到5的值。然后需要另外2点才能得到6的值,3点才

我正在研究一种自动为角色扮演游戏创建角色表的算法。在游戏中,你有一些属性,你可以在这些属性中添加点数来增加点数。但是,在某个值上,实际属性的值增加1需要2个点。从具有一定数量的点开始,默认情况下,每个属性的值为1

我有一个随机分配点的程序,但是我被困在如何在必要时将这些值(在字典中)更改为四舍五入

例如,如果我在“强度”中加3分,这很好,我得到的“强度”值为3(包括基数1)。然而,如果我加上4点,我仍然应该只有4的值。需要5个点(加上基数1)才能得到5的值。然后需要另外2点才能得到6的值,3点才能得到7的值,3点才能得到8的值

我当前用于分配attibutes的代码如下所示:

attributes = {}
row1 = ['strength', 'intelligence', 'charisma']
row2 = ['stamina', 'willpower']
row3 = ['dexterity', 'wits', 'luck']

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)

assignRow(row1, 7)
assignRow(row2, 5)
assignRow(row3, 3)
我想要的只是一个简单的函数,它将字典“attributes”作为参数,并将每个属性的点数转换为它应该具有的正确值

i、 e.
“力量”:4
保持为
“力量”:4
,但
“智慧”:6
下降为
“智慧”:5
“智慧”:9
下降为
“智慧:7”

我对使用字典有点陌生,因此我通常的做法是:

def convert(list):
    for i in range(len(list)):
        if list[i] <= 4:
            list[i] = list[i]
        if list[i] in (5, 6):
            list[i] -= 1
        if list[i] in (7, 8):
            list[i] -= 2
        if list[i] in (9, 10):
            list[i] = 6
        if list[i] in (11, 12, 13):
            list[i] = 7
        else:
            list[i] = 8
def转换(列表):
对于范围内的i(len(列表)):

如果list[i]您可以使用
dictionary.items()
然后,您可以修改转换函数:

def convert(attributes):
    for key, value in attributes.items():
        # do your conversion on value here
        if value <= 4:
            continue # do nothing for this element
        elif value in (5, 6):
            value -= 1
        elif value in (7, 8):
            value -= 2
        elif value in (9, 10):
            value = 6
        elif value in (11, 12, 13):
            value = 7
        else:
            value = 8

        # to replace the value in the dictionary you can use
        attributes[key] = new_value
def convert(x):
    return x - (x > 4) - (x > 6) - (x > 8) * (x - 8) + (x > 10) + (x > 13)
def转换(属性):
对于键,attributes.items()中的值:
#在这里进行值的转换

如果值经过多次尝试和错误,这里有一个线性函数:

def convert(attributes):
    for key, value in attributes.items():
        # do your conversion on value here
        if value <= 4:
            continue # do nothing for this element
        elif value in (5, 6):
            value -= 1
        elif value in (7, 8):
            value -= 2
        elif value in (9, 10):
            value = 6
        elif value in (11, 12, 13):
            value = 7
        else:
            value = 8

        # to replace the value in the dictionary you can use
        attributes[key] = new_value
def convert(x):
    return x - (x > 4) - (x > 6) - (x > 8) * (x - 8) + (x > 10) + (x > 13)
这里有一个测试:

print([(points, convert(points)) for points in range(20)])
# [(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 4), (6, 5), (7, 5), (8, 6), (9, 6), (10, 6), (11, 7), (12, 7), (13, 7), (14, 8), (15, 8), (16, 8), (17, 8), (18, 8), (19, 8)]
不过,
if
elif
语句可能更清晰


此函数仅将大量输入点转换为一个值。您可以将
convert
函数应用于列表中的每个元素。

与“convert”函数相比,空间稍小一些,但仍然是手工操作:

p_to_v = {1:1, 2:2, 3:3, 4:4, 5:4, 6:5, 7:5, 8:6} # 'translator' dict, fill up further
input = {'strength':6, 'wits':8} # dict with stats and their points
output = dict((stat, p_to_v[point]) for stat, point in input.items()) # {'strength':5, 'wits':6}
如果你想让你的“翻译器”减少手工工作量,更好地扩展,那么你可以通过一些代码预先生成它,这取决于你的点对值逻辑。

似乎algo非常适合你的需要-点对“投资”“始终进行排序和定义。创建带有参考点的数组,如果
s:

>>> from bisect import bisect
>>> points_to_invest = [1, 2, 3, 4, 6, 8, 10, 13]
>>> bisect(points_to_invest, 1)
1
>>> bisect(points_to_invest, 4)
4
>>> bisect(points_to_invest, 5)
4
>>> bisect(points_to_invest, 6)
5

这种方法将使您在将来更易于维护

我很感激作为一名初学者,您在提出问题之前花了时间和精力制定了自己的解决方案。无论它的效率有多低,您将能够更好地理解其他解决方案,并且您已经成长为一名程序员。也就是说,不要使用内置名称
list
的名称。通常至少使用
列表
。这并不是说你的代码会立即中断,而是你将无法再调用内置函数来将内容转换为列表。另外,行
row=list
几乎没有任何用处。只需调用输入参数
row
,一举两得。@mad谢谢,我已经更新了
convert
示例中您正在使用的
list
程序。但是,以后不要更改问题的代码,特别是如果已经有答案,除非复制错误。随问随改会使现有答案失效,并使帮助您变得更加困难。啊,好吧,我会避免这样做。这非常有效,谢谢!(虽然在最后一行中,您必须将其更改为
attributes[key]=value
,因为新的\u值在其他任何地方都不存在)非常感谢您的回答,但另一行帮助我了解需要更改的内容,并为我提供了更清晰的解决方案。谢谢,这看起来确实更快,我将把它放在程序中,对另一个做一些速度测试。另外,翻译的想法也很有帮助,但目前的答案帮助我理解了我所挣扎的差异。这正是我所寻找的!非常感谢。将它转换为我需要的函数格式的最佳方法是什么?我误解了Mb,但我认为这里的主要问题是获取属性值。如果你有这个想法,rest很简单——迭代
属性\u dict.items()
并通过对分获得值。如果你已经尝试过这个方法,但仍然有问题-请在stackoverflow上创建新问题,它的方式比详细的单一问题更好对不起,现在它工作得很好,我只是把它放在下面问题的前两行下面。@FreddieR。将此答案与列表理解结合起来。将范围内i(len(list))的整个循环
替换为仅
返回[对分(点到点,x)表示列表中的x]
。使用该函数的返回值(现在是一行函数)替换输入列表。这不是一个列表,而是一个字典,因此我使用
作为键,属性中的值。items():
,在下面的答案中建议,但谢谢。