【问题标题】:How to restrict the value range in dictionary?如何限制字典中的值范围?
【发布时间】:2019-01-26 11:31:25
【问题描述】:

我想对字典中的值施加限制。 例如,假设我有以下字典

speed = {
    'x': 8,
    'y': 0,
    'z': 4}

我希望速度字典中x-key对应的值总是小于10。 例如,如果我在某些功能中使用它

    calcuate_speed(speed)

或 如果我实现一些数学变换

    speed["x"] += 1 

该值不应大于我定义的某个限制。 最简单的处理方法是什么?

【问题讨论】:

  • 不清楚你在问什么。考虑到您只能拥有 1 个 x 键,并且您正在针对它存储一个标量,什么是“x 轴”
  • 您想一开始就避免在字典中设置此类值吗?
  • 你想达到什么目的
  • 好的,我会编辑我的问题
  • 为什么不创建一个具有 x,y,z 属性的类呢?

标签: python variables syntax


【解决方案1】:

您可以通过以下方式进行:

from collections import UserDict


class MyDict(UserDict):
    def __setitem__(self, key, value):
        if value > 10: # any validation
            raise ValueError('Too big!')

        super().__setitem__(key, value)

但最好使用带有property 的类。

完整版:

from collections import UserDict

from math import sqrt


class VectorDict(UserDict):
    def __init__(self, *args, speed_limit, **kwargs):
        self.speed_limit = speed_limit
        super().__init__(*args, **kwargs)

    def __setitem__(self, key, value):
        if self._calc_speed(key, value) > self.speed_limit:
            raise ValueError('Too big!')

        super().__setitem__(key, value)

    def _calc_speed(self, replace_key=None, replace_value=0):
        square_sum = 0
        for key, value in self.items():
            if key == replace_key:
                value = replace_value

            square_sum += value ** 2

        return sqrt(square_sum)

    @property
    def speed(self):
        return self._calc_speed()


example_1d = VectorDict(x=1, speed_limit=5)
example_2d = VectorDict(x=1, y=5, speed_limit=7)
example_3d = VectorDict(x=1, y=5, z=3, speed_limit=13)

print(example_3d.speed)
example_3d['x'] += 10 # ValueError: Too big!

【讨论】:

  • 具有属性的类是一个有趣的选择。谢谢
【解决方案2】:

只需在您的周期中添加一些价值控制。 例如:

if (speed['x'] >= 10):
        speed['x'] = 9

【讨论】:

    【解决方案3】:

    用属性speed定义一个类MyClass

    class MyClass:
        def __init__(self):
            self.speed = 0
    
        def __setattr__(self, k, v):
            if k == 'speed' and v > 10: 
                return
            self.__dict__[k] = v
    

    在这里,如果 speed 不是有效值,我将忽略对它的任何更改,但您可以根据需要以不同方式处理它(例如引发异常)

    这是一个演示:

    m = MyClass()
    m.speed = 8 
    print(m.speed)
    m.speed += 1
    print(m.speed)
    m.speed += 1
    print(m.speed)
    m.speed += 1
    print(m.speed)
    

    我们得到以下输出:

    8
    9
    10
    10
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-04
      • 2014-11-01
      • 1970-01-01
      • 2020-04-13
      • 2018-03-26
      • 2019-09-22
      相关资源
      最近更新 更多