Нечетное поведение вложенного словаря в Python - PullRequest
0 голосов
/ 12 марта 2010

У меня два новых питона и я пытаюсь вырастить словарь словарей. Я сделал это в php и perl, но python ведет себя очень по-разному. Я уверен, что это имеет смысл для тех, кто более знаком с питоном. Вот мой код:

colnames = ['name','dob','id'];
tablehashcopy = {};
tablehashcopy = dict.fromkeys(colnames,{});

tablehashcopy['name']['hi'] = 0;
print(tablehashcopy);

Выход:

{'dob': {'hi': 0}, 'name': {'hi': 0}, 'id': {'hi': 0}}

Проблема возникает от 2-го до последнего утверждения (я положил печать для удобства). Я ожидал найти, что один элемент был добавлен в словарь 'name' с ключом 'hi' и значением 0. Но эта пара ключ-значение была добавлена ​​в КАЖДЫЙ подсловарь. Почему?

Я проверил это на моей машине с Ubuntu в Python 2.6 и Python 3.1, поведение одинаковое.

Ответы [ 4 ]

3 голосов
/ 12 марта 2010

Проблема связана с вашим звонком с клавиатуры. Вы передали ему пустой словарь, и он использовал тот же пустой словарь, что и значение для всех ключей. Поскольку в качестве значения используется точно такой же словарь, добавление к нему элемента означает, что вы увидите этот же элемент для всех словарей ключей.

2 голосов
/ 12 марта 2010

Как говорит msalib, ваша проблема в том, что dict.fromkeys заставляет все записи в словаре указывать на один и тот же объект. Попробуйте вместо этого создать отдельный пустой словарь для каждого ключа:

tablehashcopy=dict((key,{}) for key in colnames)
1 голос
/ 12 марта 2010

В вашем источнике только один внутренний объект словаря создается и используется 3 раза.Поэтому, когда вы модифицируете его, вы также увидите изменение 3 раза, потому что все связано с одной и той же переменной.

Вы можете сделать что-то вроде следующего, чтобы решить проблему.Это создаст несколько (key, {}) кортежей и использует их для создания словаря:

colnames = ['name','dob','id']
tablehashcopy = dict((k, {}) for k in colnames)
tablehashcopy['name']['hi'] = 0
print tablehashcopy   # use "print(tablehashcopy)" in Python 3
# output: {'dob': {}, 'name': {'hi': 0}, 'id': {}}

Пожалуйста, обратите также внимание на форматирование (без точек с запятой) и некоторые операторы, которые я удалил, потому что они были ненужными.

1 голос
/ 12 марта 2010

dict.fromkeys (seq, [value]) - значение по умолчанию равно None, если ничего не передается, но, поскольку вы передали dict вместо этого, это то, что он использует для каждой пары ключ-значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...