Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
438 views
in Technique[技术] by (71.8m points)

python - How can I properly copy nested dictionary objects?

I'm working on a project with Python 2.7 where I have a "complex" dictionary structure, and I was trying to do something like this:

generic_dict = {
     'user': {'created': {}, 'modified': {}, 'errors': {}},
     'usermon': {'created': {}, 'modified': {}, 'ignored': {}, 'errors': {}}


log_data = {
    'esp': generic_dict,
    'por': generic_dict,
    'sui': generic_dict,
    'ben': generic_dict,
    'mex': generic_dict,
    'arg': generic_dict,
}

I was trying to use the generic dict to avoid repeating code but I have a problem if I do like this, when I modify any of the country dicts (esp, ben, por) all are modifying at the same time.

Let's assume the dictionary is empty and I do this

log_data['esp']['user']['created']['today'] = 'asdasdasda'

all the other dicts now have the same value like generic_dict is the same all of them.

print log_data['ben']['user']['created']
Output: {'today': 'asdasdasda'}
print log_data['ben']['user']['created']
Output: {'today': 'asdasdasda'}

I understand what's happening but I don't know how to avoid that

  • Which is the best way copy nested dictionary objects ?
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can use copy.deepcopy to create a new copy of the generic_dict object, like this

from copy import deepcopy

log_data = {
    'esp': deepcopy(generic_dict),
    'por': deepcopy(generic_dict),
    'sui': deepcopy(generic_dict),
    'ben': deepcopy(generic_dict),
    'mex': deepcopy(generic_dict),
    'arg': deepcopy(generic_dict),
}

Otherwise, you can have a constructor function, like this

def generic_dict():
    return {'user': {'created': {}, 'modified': {}, 'errors': {}},
            'usermon': {'created': {}, 'modified':{}, 'ignored': {}, 'errors': {}}}

And then call it to create a new dictionary object every time, like this

log_data = {
    'esp': generic_dict(),
    'por': generic_dict(),
    'sui': generic_dict(),
    'ben': generic_dict(),
    'mex': generic_dict(),
    'arg': generic_dict(),
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...