Словарь списков для вложенного словаря - PullRequest
6 голосов
/ 03 июня 2019

У меня есть следующий словарь {44: [0, 1, 0, 3, 6]}, и мне нужно преобразовать его в dict1 = {44: {0:0, 1:1, 2:0, 3:3, 4:6}}, но мой цикл for не работает:

maxnumbers = 5          #this is how many values are within the list
for i in list(range(maxnumbers)):
    for k in list(dict1.keys()):
        for g in dict1[k]:
            newdict[i] = g
print(num4)

Можете ли вы помочь мне? Заранее спасибо.

Ответы [ 4 ]

13 голосов
/ 03 июня 2019

Вы можете использовать словарное понимание с enumerate:

d = {44: [0, 1, 0, 3, 6]}

{k:dict(enumerate(v)) for k,v in d.items()}
# {44: {0: 0, 1: 1, 2: 0, 3: 3, 4: 6}}
5 голосов
/ 03 июня 2019

Используйте простое вложенное словарное понимание, которое использует enumerate:

d = {44: [0, 1, 0, 3, 6]}

print({k: {i: x for i, x in enumerate(v)} for k, v in d.items()})
# {44: {0: 0, 1: 1, 2: 0, 3: 3, 4: 6}}
2 голосов
/ 03 июня 2019
a = {44: [0, 1, 0, 3, 6]}
a= {i:{j:a[i][j] for i in a for j in range(len(a[i]))}}

print(a)

выход

 {44: {0: 0, 1: 1, 2: 0, 3: 3, 4: 6}}
1 голос
/ 03 июня 2019

Почему ваша текущая реализация не работает:

for i in list(range(maxnumbers)):
    for k in list(dict1.keys()):
        for g in dict1[k]:
            # this will iterate over all of the values in
            # d1[k] and the i: v pair will be overwritten by
            # the last value
            newdict[i] = g

В пошаговом виде это будет выглядеть так:

# for value in [0, 1, 0, 3, 6]: Just take this set of values as an example

# first, value is 0, and say we are on i = 1, in the outer for loop
newdict[1] = 0

# Then it will progress to value = 1, but i has not changed
# which overwrites the previous value
newdict[1] = 1

# continues until that set of values is complete

Чтобы это исправить, вам нужно, чтобы i и значения dict1[k] увеличивались вместе. Это можно сделать с помощью zip:

for index, value in zip(range(maxnumbers), dict1[k]):
    newdict[index] = value

Также, если вам нужен доступ к обоим значениям ключей и , используйте dict.items():

for k, values in dict1.items():
    # then you can use zip on the values
    for idx, value in zip(range(maxnumbers), values):

Однако функция enumerate уже облегчает это:

for k, values in dict1.items():
    for idx, value in enumerate(values):
        # rest of loop

Это более надежно, поскольку вам не нужно находить, что maxnumbers опережает время.

Чтобы сделать это в традиционном цикле for, который вы использовали:

new_dict = {}

for k, v in dict1.items():
    sub_d = {} # create a new sub_dictionary
    for i, x in enumerate(v):
        sub_d[i] = x
    # assign that new sub_d as an element in new_dict
    # when the inner for loop completes
    new_dict[k] = sub_d

Или, более компактно:

d = {44: [0, 1, 0, 3, 6]}
new_d = {}

for k, v in d.items():
   new_d[k] = dict(enumerate(v))

Где конструктор dict будет принимать итеративный 2-элементный tuples в качестве аргумента, который enumerate предоставляет

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