二维字典分配不符合预期

时间:2016-02-26 08:13:51

标签: python dictionary

该功能的回报不符合预期。

我的环境py2.7.11 centos6.5。

我希望函数像这样返回返回

{'www.baidu.com': {'3xx': 0, 'response_time': 0.126, '5xx': 0, '4xx': 1}, 
'www.google.com': {'3xx': 0, 'response_time': 0, '5xx': 0, '4xx': 0}}

但实际上它是这样的回归。不应分配send_dict['www.google.com']['response_time']send_dict['www.google.com']['response_code']。但为什么呢?

{'www.baidu.com': {'3xx': 0, 'response_time': 0.126, '5xx': 0, '4xx': 1}, 
'www.google.com': {'3xx': 0, 'response_time': 0.126, '5xx': 0, '4xx': 1}}

Python代码:

#!/usr/bin/python
# -*- coding: utf-8 -*-

sink_dict = {'sink_zabbix_monitor_keys': '3xx,4xx,5xx,response_time',
             'sink_zabbix_domain_keys': 'www.baidu.com,www.google.com'}
sub_send_dict = dict.fromkeys(sink_dict['sink_zabbix_monitor_keys'].split(','), 0)
send_dict = dict.fromkeys(sink_dict['sink_zabbix_domain_keys'].split(','), sub_send_dict)


def calculate_item(item):

    response_code_dict = dict.fromkeys(sink_dict['sink_zabbix_domain_keys'].split(','), 0)
    response_time_dict = dict.fromkeys(sink_dict['sink_zabbix_domain_keys'].split(','), 0)
    domain = item['domain']
    response_code_dict[domain] = int(item['response_code'])
    response_time_dict[domain] = float(item['response_time'])
    if domain in send_dict:
        print domain
        if response_time_dict[domain] > float(send_dict[domain]['response_time']):
            send_dict[domain]['response_time'] = response_time_dict[domain]
        send_dict[domain][str(response_code_dict[domain])[0] + "xx"] += 1
    return send_dict

tmp_item = {'domain': 'www.baidu.com', 'response_time': '0.126', 'response_code': '401'}
tmp_item1 = {'domain': 'www.google.com', 'response_time': '0.126', 'response_code': '401'}
tmp_item2 = {'domain': 'www.baidu.com', 'response_time': '0.166', 'response_code': '401'}

print calculate_item(tmp_item)

1 个答案:

答案 0 :(得分:0)

你走了:

send_dict = {k: sub_send_dict.copy() for k in sink_dict['sink_zabbix_domain_keys'].split(',')}

这称为dict理解。这是有效的,因为我正在为密钥分配shallow copy字典。 dict.fromkeys()会将值分配给每个密钥,所有密钥将共享相同的sub_send_dict引用。

来自(链接)python文档:

  

Python中的赋值语句不复制对象,它们在目标和对象之间创建绑定。对于可变或包含可变项目的集合,有时需要一个副本,因此可以更改一个副本而不更改另一个副本。