Python 3 добавляет элементы в список независимо от ключа, используемого в dict

1

У меня есть dict, который я определил с помощью:

keys = ['Valid', 'Reverse']
NOC = dict.fromkeys(keys, [])

Затем я перебираю файл и на основе элементов в строках добавляю их в разные списки в этом dict, основываясь на значении в строке

Это код внутри понимания списка, проходящего через содержимое считывателя:

if item[0] == '4':
    if float(item[10]) < 0:
        state = 'Reverse'
        print(state)
        NOC[state].append(item[6]+"FOOOO")
    if float(item[10]) >= 0:
        state = 'Valid'
        print(state)
        NOC[state].append(item[6])

    print (NOC['Reverse'])

Как вы можете видеть, я добавляю строку "FOOOO" в случае "Реверс". Я сделал это, чтобы посмотреть, что происходит внутри списков в dict.

Я подтвердил, что инструкции if-then работают правильно.

Тем не менее, добавление, кажется, пишет в том же месте в памяти. Это странно. Ниже приведено несколько примеров обработки списка, проходящих через содержимое файла:

Valid
['68382011714']
Valid
['68382011714', '69315013701']
Valid
['68382011714', '69315013701', '16729018201']
Valid
['68382011714', '69315013701', '16729018201', '54458098010']
Valid
['68382011714', '69315013701', '16729018201', '54458098010', '61570007301']
Valid
['68382011714', '69315013701', '16729018201', '54458098010', '61570007301', '61570007301']
Reverse
['68382011714', '69315013701', '16729018201', '54458098010', '61570007301', '61570007301', '61570007301FOOOO']

Для меня нет никакого смысла, что печать (NOC ['Reverse']) показывает значения, которые имеют что-то иное, чем те, у которых есть добавленный "FOOOO". Почему это происходит?

Теги:
list
dictionary

4 ответа

3
Лучший ответ

Вы создаете только один список:

NOC = dict.fromkeys(keys, [])

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

assert NOC["Valid"] is not NOC["Reverse"], "It the same list!"

Вместо этого убедитесь, что каждый ключ получает свой собственный список:

NOC = {k: [] for k in keys}
  • 0
    Я люблю Python, потому что ответы часто бывают такими простыми. Спасибо за помощь. Я потратил на это два часа и ни разу не подумал, что создаю единый список из-за того, как я создавал переменные. Спасибо Спасибо спасибо.
0

Здесь проблема в том, что все значения указывают на один и тот же список. Эффективное и Pythonic решение было бы использовать collections.defaultdict.

from collections import defaultdict
NOC = defaultdict(list)

Надеюсь, он удовлетворит ваши требования.

0

Если предоставленное значение является изменяемым объектом (значение которого может быть изменено) подобно списку, словарю и т.д., Когда изменяемый объект изменяется, каждый элемент последовательности также обновляется.

Это связано с тем, что каждому элементу присваивается ссылка на тот же объект (указывает на тот же объект в памяти). вы должны использовать keys = ['Valid', 'Reverse'] NOC = { key: [] for key in keys } понимания словаря keys = ['Valid', 'Reverse'] NOC = { key: [] for key in keys }

  • 0
    Я хотел бы пометить все ответы правильно, но большое спасибо, Иро
0

Проблема в том, что значение для обоих ключей имеет одинаковую ссылку, когда вы создаете словарь из клавиш с помощью NOC = dict.fromkeys(keys, [])

>>> keys = ['Valid', 'Reverse']
>>> NOC = dict.fromkeys(keys, [])
>>> NOC
{'Valid': [], 'Reverse': []}
>>> id(NOC['Valid'])
50173312
>>> id(NOC['Reverse'])
50173312

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

>>> keys = ['Valid', 'Reverse']
>>> NOC = dict.fromkeys(keys, [])
>>> for key in NOC.keys():
...     NOC[key] = []
...
>>> NOC
{'Valid': [], 'Reverse': []}
>>> id(NOC['Valid'])
50173312
>>> id(NOC['Reverse'])
11515384

Теперь приложение прекрасно работает.

  • 0
    Хотелось бы пометить все ответы правильно - но большое спасибо Круши

Ещё вопросы

Сообщество Overcoder
Наверх
Меню