Python Словарь не печатается, как я ожидал - PullRequest
0 голосов
/ 03 мая 2020

Я работал над сценарием python, где, учитывая список, состоящий из трех списков, он создаст словарь, в котором будут храниться пары ключ-значение, где ключи представляют (строку, столбец) списка как кортежи и соответствующие значения являются списочными значениями для этой указанной c позиции. Вот что у меня есть:

EMPTY = None

board_2 = [
    [EMPTY, EMPTY, EMPTY],
    [EMPTY, EMPTY, EMPTY],
    [EMPTY, EMPTY, EMPTY]
    ]

board_position = {}
for row in board_2:
    for cell in row:
        board_position[(board_2.index(row), row.index(cell))] = board_2[board_2.index(row)][row.index(cell)]

print(board_position)

Я ожидаю, что он напечатает словарь, в котором все девять ключей будут иметь None в качестве значений; но вместо этого я просто получаю это взамен:

{(0, 0): None}

Кажется, словарь остановился после того, как ему была дана только первая пара ключ-значение, а потом все проигнорировано. Я предположил, что в моем коде что-то не так, например, отключение логики c возможно во вложенном l oop. И все же невероятно, что когда я решил создать другую версию board_2, на этот раз board_1, где board_1 имели разные значения в списках, мой код, казалось, работал:

Ввод:

board_1 = [
   ['00', '01', '02'],
   ['10', '11', '12'],
   ['20', '21', '22']
   ]

board_position = {}
for row in board_1:
    for cell in row:
        board_position[(board_1.index(row), row.index(cell))] = board_1[board_1.index(row)][row.index(cell)]

print(board_position)

Вывод:

{(0, 0): '00', (0, 1): '01', (0, 2): '02', (1, 0): '10', (1, 1): '11', (1, 2): '12', (2, 0): '20', (2, 1): '21', (2, 2): '22'}
{'a': 1, 'b': 1}

Кажется, теперь это работает. Единственное различие, которое я вижу между двумя версиями платы, состоит в том, что значения внутри списков отличаются; но я не понимаю, почему это имеет значение. Мне известно, что если ранее добавленный ключ добавляется в словарь, словарь обновит существующий ключ новым значением. Но похоже, что ключи разные; значения, хотя и одинаковы. Я что-то здесь упускаю, мой код неверен, или я должен что-то еще сейчас сказать о python словарях? Любая помощь будет оценена.

Ответы [ 3 ]

2 голосов
/ 03 мая 2020

Индекс возвращает первое вхождение значения в списке - следовательно, все ваши EMPTY находятся в позиции 0. И добавляются как (0,0). Вы перезаписываете один и тот же ключ снова и снова - таким образом, у вас есть только этот ключ в полученном словаре.

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

Лучше использовать перечислять вместо:

EMPTY = None

board_2 = [
    [EMPTY, EMPTY, EMPTY],
    [EMPTY, EMPTY, EMPTY],
    [EMPTY, EMPTY, EMPTY]
    ]

board_1 = [
   ['00', '01', '02'],
   ['10', '11', '12'],
   ['20', '21', '22']
   ]

for b in (board_2, board_1):
    board_position = {}
    for id1, row in enumerate(b):
        for id2,cell in enumerate(row):
            board_position[(id1,id2)] = cell

    print(board_position)

Вывод:

{(0, 1): None, (1, 2): None, (0, 0): None, (2, 1): None, (1, 1): None, 
 (2, 0): None, (2, 2): None, (1, 0): None, (0, 2): None}

{(0, 1): '01', (1, 2): '12', (0, 0): '00', (2, 1): '21', (1, 1): '11', 
 (2, 0): '20', (2, 2): '22', (1, 0): '10', (0, 2): '02'}

или короче, как диктовка:

d = { (r,c):cell for r,x in enumerate(board_1) for c,cell in enumerate(x) }
1 голос
/ 03 мая 2020

В вашей первой реализации все строки и ячейки имеют одно и то же значение, поэтому при вызове list.index он получает первое появление идентичного подсписка. В этом случае вы захотите использовать enumerate для записи значений итерации, например:

for i, row in enumerate(board_1):
    for j, cell in enumerate(row):
        board_position[(i, j)] = cell
0 голосов
/ 03 мая 2020

Проблема здесь заключается в функции index, она просматривает данный список, чтобы найти значение first, которое соответствует. Когда массивы пусты, он ищет массив [None, None, None]. Это будет соответствовать строке first каждый раз! Аналогично при поиске индекса каждого элемента в каждой строке. Намного лучше и эффективнее использовать счетчик:

row_pos = 0
for row in board_1:
    cell_pos = 0
    for cell in row:
        board_position[(row_pos, cell_pos)] = board_1[row_pos][cell_pos]
        cell_pos += 1
    row_pos += 1

print(board_position)
...