Python вставка и удаление словаря - PullRequest
1 голос
/ 28 февраля 2020
print("Before deleting:\n") 

od = {}

od['a'] = 1

od['b'] = 2

od['c'] = 3

od['d'] = 4

for key, value in od.items(): 

    print(key, value) 

print("\nAfter deleting:\n") 

od.pop('c') 

for key, value in od.items(): 

    print(key, value) 

print("\nAfter re-inserting:\n") 

od['c'] = 3

for key, value in od.items(): 

      print(key, value)

После запуска я получаю

Перед удалением:

('a', 1)
('c', 3)
('b', 2)
('d', 4)

После удаления:

('a', 1)
('b', 2)
('d', 4)

После повторной вставки:

('a', 1)
('c', 3)
('b', 2)
('d', 4)

Мой вопрос, почему c вставляется на втором месте, а для записи, каким бы ни было значение c, он всегда вставляется на втором месте. Заранее спасибо

Ответы [ 4 ]

1 голос
/ 28 февраля 2020

Вы на самом деле на Python 2, а не Python 3, о чем свидетельствуют результаты ваших print с; print - это оператор для Python 2 (без кода, включая from __future__ import print_function вверху), а не для вызова функции (как это происходит в Py3 или в Py2 с импортом __future__), поэтому круглые скобки просто сделал tuple, который вы напечатали.

До Python 3.6, dict s не имеют никакого полезного порядка (он привязан к га sh клавиш, но разрешение коллизий означает порядок может измениться просто потому, что dict был создан в другом порядке), но при повторной вставке данного ключа часто (не гарантируется) помещает его в тот же сегмент, сохраняя его в той же позиции итерации.

Если вы ищете упорядоченное поведение вставки (вы хотите, чтобы 'c' переместился в конец), либо обновите его до Python 3.6+ (требуется 3.7+, чтобы гарантировать его, но оно есть у всех существующих интерпретаторов 3.6) в качестве детали реализации), или используя collections.OrderedDict.

0 голосов
/ 28 февраля 2020

Python словари реализованы с использованием таблиц ha sh . Это массив, индексы которого получены с помощью функции ha sh для клавиш.

Для любой заданной клавиши (скажем, это строка) она сначала проходит через функцию ha sh, а затем маскирует это с (arr_size -1). Всего: hash_fun c ('a') & (arr_size -1) дает индекс пары ключ-значение в массиве.

(k , v) -------------> index (n = 8) (k, v)

(a, 1) ---- h ('a') & 7 -> 0 (a, 1)

(b, 2) ---- h ('b') & 7 -> 1 (b, 2)

(c , 1) ---- h ('c') & 7 -> 2 (c, 3)

Именно поэтому индекс ключа 'c' не меняется.

ср c

0 голосов
/ 28 февраля 2020

Начиная с Python 3.7, порядок вставки Python словарей гарантирован

0 голосов
/ 28 февраля 2020

Обратите внимание, что словари в python неупорядочены - поскольку значения в словаре индексируются по ключам, они не хранятся в каком-либо определенном порядке.

...