【问题标题】:Insertion Problem with Multiple-Value Python Dictionary多值 Python 字典的插入问题
【发布时间】:2019-07-16 12:24:25
【问题描述】:

我是 Python 新手,所以请放轻松。我正在使用字典为一个键存储多个值,但是,当我尝试更新值时遇到问题。这是我设置字典的方法;首先,我使用setdefault() 编写第一个值:

dictionary.setdefault(id.ID, []).append(id.enterTime)
dictionary.setdefault(id.ID, []).append(id.duration)
dictionary.setdefault(id.ID, []).append(id.enter)
dictionary.setdefault(id.ID, []).append(id.exit)
dictionary.setdefault(id.ID, []).append(id.standing)
dictionary.setdefault(id.ID, []).append(id.sitting)

为了解释起见,假设它在打印时产生以下输出:

{0: [5, 120, 0, 0, 0, 0]}

当 id.enter 实例变量更改时,我使用以下代码更新字典,只需删除原始值并将新值附加到字典:

dictionary[id.ID].remove(id.enter)
dictionary[id.ID].insert(2, id.enter)

字典打印如下:

{0: [5, 120, 1, 0, 0, 0]}

稍后在程序中,实例变量 id.exit 变为 1。我尝试在字典中将退出值从 0 更新为 1 后更改如下:

dictionary[id.ID].remove(id.exit)
dictionary[id.ID].insert(3, id.exit)

我知道这样做的方法很糟糕,但我认为这是更新值的最简单方法。当我这样做时,会出现问题,因为它将id.enter 更改回其原始值但更新id.exit

{0: [5, 120, 0, 1, 0, 0]}

有人知道为什么会这样吗?谢谢。

【问题讨论】:

  • 为什么不在字典中存储对象?修改值会更容易。另请参阅 python 3 中的 dataclasses
  • remove() 删除列表中与参数匹配的 first 值。您传递了id.exitnew 值,恰好等于id.enterold 值(存储在索引2,而不是3)。当从列表中删除一个元素时,所有存储在它之后的元素都会向后移动 1 个空格,因此 id.enter 的新值变为 id.exit 值(原为 0)。
  • @meowgoesthedog 谢谢你的信息。这种修改列表的方法会奏效吗,或者这是一种天真的方式来改变它?
  • @cz46 依赖存储顺序是一种糟糕的方法 - 直接存储 id 对象或使用字典 / namedtuple 代替。

标签: python dictionary key-value


【解决方案1】:

使用@mkrieger1 的答案解释了您的代码的问题/错误并提供了快速解决方案。

另一种存储数据的方法可能是使用嵌套字典,以使其更清晰且不易出错:

my_dict = {
    id.ID: {
        'enterTime': id.enterTime,
        'duration': id.duration,
        'enter': id.enter,
        'exit': id.exit,
        'standing': id.standing,
        'sitting': id.sitting,
    }
}

defaultdict 甚至更好:

import collections
my_dict = collections.defaultdict(lambda: {
    'enterTime': 0,
    'duration': 0,
    'enter': 0,
    'exit': 0,
    'standing': 0,
    'sitting': 0,
})
print(my_dict)
# defaultdict(<function <lambda> at 0x7f327d094ae8>, {})

# add a new ID, it creates the nested dict automatically
my_dict[object_1.ID]['exit'] = object_1.exit
print(my_dict)
# defaultdict(<function <lambda> at 0x7f327d094ae8>, {1: {'enterTime': 0, 'duration': 0, 'enter': 0, 'exit': 5, 'standing': 0, 'sitting': 0}})

【讨论】:

    【解决方案2】:

    tutorial中所述:

    list.remove(x)
    从列表中删除值等于 x 的第一项。如果没有这样的项目,它会引发 ValueError。

    如果你有清单

    [5, 120, 1, 0, 0, 0]
    

    并使用remove(id.exit),当id.exit等于1时,列表变为:

    [5, 120, 0, 0, 0]
    

    作为一个简单的解决方案,而不是

    dictionary[id.ID].remove(id.exit)
    dictionary[id.ID].insert(3, id.exit)
    

    随便用

    dictionary[id.ID][3] = id.exit
    

    【讨论】:

    • 非常感谢。我很感激。
    • 虽然这个答案在技术上是正确的并且确实回答了这个问题,但建议用户不要以这​​种方式使用列表会更好 - 这些应该是元组或字典。
    • @brunodesthuilliers 随意写下这样的答案。我现在不想进入完整的代码审查模式。
    猜你喜欢
    • 1970-01-01
    • 2021-08-02
    • 1970-01-01
    • 2022-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-18
    相关资源
    最近更新 更多