【问题标题】:Setting a key's value, changes all the values for all keys设置键的值,更改所有键的所有值
【发布时间】:2019-10-26 23:48:02
【问题描述】:

在遍历字典时,我将键的值分配给另一个字典的匹配键,但是当我这样做时,它会更改字典中所有键的值,而不仅仅是匹配键输入。

由于某种原因,这在 Sublime 中可以正常工作,但在 PyCharm 中运行完全相同的代码时就无法正常工作。

categories_ranges = {'MILES': 
                    {'CATEGORIES': ['TOTPOP_CY', 'TOTHH_CY', 'MEDHINC_CY', 
                    'AVGHINC_CY', 'BACHDEG_CY', 'GRADDEG_CY', 'MEDAGE_CY', 
                    'FAMHH_CY', 'OCCARCH_CY', 'OCCBLDG_CY', 'OCCFARM_CY', 
                    'OCCCONS_CY', 'OCCMAIN_CY', 'OCCTRAN_CY'], 
                    'RANGES': [[1, 2, 3, 5]]}, 'MINUTES': 
                    {'CATEGORIES': '', 'RANGES': ''}}
organized_output = {
'TOTPOP_CY': {'MILES': {1: 0, 2: 0, 3: 0, 5: 0}, 'MINUTES': {}},
'TOTHH_CY': {'MILES': {1: 0, 2: 0, 3: 0, 5: 0}, 'MINUTES': {}}, 
'MEDHINC_CY': {'MILES': {1: 0, 2: 0, 3: 0, 5: 0}, 'MINUTES': {}}, 
'AVGHINC_CY': {'MILES': {1: 0, 2: 0, 3: 0, 5: 0}, 'MINUTES': {}}, 
'BACHDEG_CY': {'MILES': {1: 0, 2: 0, 3: 0, 5: 0}, 'MINUTES': {}}, 
'GRADDEG_CY': {'MILES': {1: 0, 2: 0, 3: 0, 5: 0}, 'MINUTES': {}}, 
'MEDAGE_CY': {'MILES': {1: 0, 2: 0, 3: 0, 5: 0}, 'MINUTES': {}}, 
'FAMHH_CY': {'MILES': {1: 0, 2: 0, 3: 0, 5: 0}, 'MINUTES': {}}, 
'OCCARCH_CY': {'MILES': {1: 0, 2: 0, 3: 0, 5: 0}, 'MINUTES': {}}, 
'OCCBLDG_CY': {'MILES': {1: 0, 2: 0, 3: 0, 5: 0}, 'MINUTES': {}}, 
'OCCFARM_CY': {'MILES': {1: 0, 2: 0, 3: 0, 5: 0}, 'MINUTES': {}}, 
'OCCCONS_CY': {'MILES': {1: 0, 2: 0, 3: 0, 5: 0}, 'MINUTES': {}}, 
'OCCMAIN_CY': {'MILES': {1: 0, 2: 0, 3: 0, 5: 0}, 'MINUTES': {}}, 
'OCCTRAN_CY': {'MILES': {1: 0, 2: 0, 3: 0, 5: 0}, 'MINUTES': {}}
}

for key, value in categories_ranges.items():
    demogs_response = {'MILES': 
               {'TOTPOP_CY': {1: 6639, 2: 22682, 3: 39254, 5: 86086}, 
                'TOTHH_CY': {1: 2834, 2: 9149, 3: 16026, 5: 37772}, 
                'MEDHINC_CY': {1: 53505, 2: 52391, 3: 55267, 5: 67726}, 
                'AVGHINC_CY': {1: 72158, 2: 74334, 3: 80261, 5: 100634}, 
                'BACHDEG_CY': {1: 895, 2: 3221, 3: 5805, 5: 16240}, 
                'GRADDEG_CY': {1: 414, 2: 1508, 3: 3021, 5: 11027}, 
                'MEDAGE_CY': {1: 35.2, 2: 36.4, 3: 37.8, 5: 43.6}, 
                'FAMHH_CY': {1: 1545, 2: 5319, 3: 9072, 5: 20572}, 
                'OCCARCH_CY': {1: 104, 2: 382, 3: 466, 5: 956}, 
                'OCCBLDG_CY': {1: 169, 2: 905, 3: 1704, 5: 1471}, 
                'OCCFARM_CY': {1: 0, 2: 0, 3: 3, 5: 21}, 
                'OCCCONS_CY': {1: 152, 2: 791, 3: 1264, 5: 1719}, 
                'OCCMAIN_CY': {1: 177, 2: 365, 3: 507, 5: 837}, 
                'OCCTRAN_CY': {1: 200, 2: 810, 3: 1537, 5: 1955}}}

    if categories_ranges[key]['RANGES'] != '':
        for demog_field in demogs_response:
            for category in demogs_response[demog_field]:
                for _key, _value in demogs_response[demog_field][category].items():
                    organized_output[category][demog_field][_key] = _value

print("organized_output: ", organized_output)

输出应该是这样的——这在 Sublime 中也可以正常工作:

organized_output:  {'TOTPOP_CY': 
{'MILES': {1: 6639, 2: 22682, 3: 39254, 5: 86086}, 'MINUTES': {}},
'TOTHH_CY': {'MILES': {1: 2834, 2: 9149, 3: 16026, 5: 37772}, 'MINUTES': {}},
'MEDHINC_CY': {'MILES': {1: 53505, 2: 52391, 3: 55267, 5: 67726}, 'MINUTES': {}},
'AVGHINC_CY': {'MILES': {1: 72158, 2: 74334, 3: 80261, 5: 100634}, 'MINUTES': {}},
'BACHDEG_CY': {'MILES': {1: 895, 2: 3221, 3: 5805, 5: 16240}, 'MINUTES': {}},
'GRADDEG_CY': {'MILES': {1: 414, 2: 1508, 3: 3021, 5: 11027}, 'MINUTES': {}},
'MEDAGE_CY': {'MILES': {1: 35.2, 2: 36.4, 3: 37.8, 5: 43.6}, 'MINUTES': {}},
'FAMHH_CY': {'MILES': {1: 1545, 2: 5319, 3: 9072, 5: 20572}, 'MINUTES': {}},
'OCCARCH_CY': {'MILES': {1: 104, 2: 382, 3: 466, 5: 956}, 'MINUTES': {}},
'OCCBLDG_CY': {'MILES': {1: 169, 2: 905, 3: 1704, 5: 1471}, 'MINUTES': {}},
'OCCFARM_CY': {'MILES': {1: 0, 2: 0, 3: 3, 5: 21}, 'MINUTES': {}},
'OCCCONS_CY': {'MILES': {1: 152, 2: 791, 3: 1264, 5: 1719}, 'MINUTES': {}},
'OCCMAIN_CY': {'MILES': {1: 177, 2: 365, 3: 507, 5: 837}, 'MINUTES': {}},
'OCCTRAN_CY': {'MILES': {1: 200, 2: 810, 3: 1537, 5: 1955}, 'MINUTES': {}}}

目前,在 PyCharm 中,输出如下所示:

organized_output = {'TOTPOP_CY': {'MILES': {1: 200, 2: 810, 3: 1537, 5: 1955}, 'MINUTES': {}}, 'TOTHH_CY': {'MILES': {1: 200, 2: 810, 3: 1537, 5: 1955}, 'MINUTES': {}}, 'MEDHINC_CY': {'MILES': {1: 200, 2: 810, 3: 1537, 5: 1955}, 'MINUTES': {}}, 'AVGHINC_CY': {'MILES': {1: 200, 2: 810, 3: 1537, 5: 1955}, 'MINUTES': {}}, 'BACHDEG_CY': {'MILES': {1: 200, 2: 810, 3: 1537, 5: 1955}, 'MINUTES': {}}, 'GRADDEG_CY': {'MILES': {1: 200, 2: 810, 3: 1537, 5: 1955}, 'MINUTES': {}}, 'MEDAGE_CY': {'MILES': {1: 200, 2: 810, 3: 1537, 5: 1955}, 'MINUTES': {}}, 'FAMHH_CY': {'MILES': {1: 200, 2: 810, 3: 1537, 5: 1955}, 'MINUTES': {}}, 'OCCARCH_CY': {'MILES': {1: 200, 2: 810, 3: 1537, 5: 1955}, 'MINUTES': {}}, 'OCCBLDG_CY': {'MILES': {1: 200, 2: 810, 3: 1537, 5: 1955}, 'MINUTES': {}}, 'OCCFARM_CY': {'MILES': {1: 200, 2: 810, 3: 1537, 5: 1955}, 'MINUTES': {}}, 'OCCCONS_CY': {'MILES': {1: 200, 2: 810, 3: 1537, 5: 1955}, 'MINUTES': {}}, 'OCCMAIN_CY': {'MILES': {1: 200, 2: 810, 3: 1537, 5: 1955}, 'MINUTES': {}}, 'OCCTRAN_CY': {'MILES': {1: 200, 2: 810, 3: 1537, 5: 1955}, 'MINUTES': {}}}

当我在 PyCharm 的调试中运行此代码时,我可以看到每个 'MILES' 字典的值同时发生变化,这就是为什么 'MILES' 字典的每个实例都具有相同的确切值的原因。每个条目都是不同条目的一部分,因此不应发生这种情况。

我尝试将items() 的用法换成zip,但这也不起作用。我尝试将值分配过程编写为列表理解,但这也产生了相同的结果。目前,我非常确信这是 PyCharm 的一个问题。我上面提到的每一种替代方法在 Sublime 中都非常完美,但我每次在 PyCharm 中都得到相同的结果。目前,我正在运行 Python 3.6.5,以防万一。

我是否在某种程度上遗漏了某些内容,或者 PyCharm 在这些字典的迭代过程中是否存在某种固有问题?

【问题讨论】:

  • 如果我没记错的话,您不应该使用 items() 来遍历字典并同时更改字典。您遍历 items() 并创建一个中间字典。当循环结束时,您可以尝试更改/更新字典。
  • 好点,除了在这种情况下,正在修改的字典不会被迭代。也没有解释为什么 Sublime 运行良好而 PyCharm 没有,但感谢您的评论。我看看能不能对方法做些调整。
  • 看起来缩进可能从 if categories_ranges ... 开始关闭。您得到的错误结果是什么?
  • @RootTwo 缩进已关闭,但与我的原始代码相比,这更像是一个堆栈溢出问题。但是,我进行了调整以帮助澄清更多。我将编辑我的问题以包含最终错误结果的示例。
  • 试试import sys ; print(sys.version, sys.executable); print("\n".join(sys.path)) 如果pycharm和sublime有区别,那我猜你会看到上面代码行的输出有区别

标签: python dictionary pycharm


【解决方案1】:

这是我确定的最佳解决方法:

output = {}

if categories_ranges[range_type]['RANGES'] != '':
    for demog_field in demogs_response:
        for category in demogs_response[demog_field]:
            output[category] = {}
            output[category][demog_field] = {}
            for _key, _value in demogs_response[demog_field][category].items():
                output[category][demog_field][_key] = _value
    return output
else:
    return output

这不是尝试为初始字典中的键分配新值,而是形成一个新字典并在迭代之前的字典时重新构建它。

【讨论】:

    猜你喜欢
    • 2019-04-09
    • 1970-01-01
    • 2023-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-12
    • 2022-01-18
    • 2017-10-23
    相关资源
    最近更新 更多