У меня есть список, который выглядит следующим образом:

list1 = [  [0,  4,  2,  5,  0,  0],
           [4,  0,  0,  0,  6,  4],
           [2,  0,  0,  7,  0,  0],
           [5,  0,  7,  0,  5,  3],
           [0,  6,  0,  5,  0,  1],
           [0,  4,  0,  3,  1,  0],
        ]

Который я хочу преобразовать в словарь следующим образом:

G = {'a' : { 'b':4, 'c':2, 'd':5},
     'b': {'a':4,'e':  6,'f':4},
     'c':{ 'a':2,'d':7},
     'd':{'a':5, 'c':7, 'e':5,'f':3},
     'e':{'b':6, 'd':5,'f':1},
     'f' :{'b':4, 'd':3,'e':1}
 }

У меня есть следующий код, чтобы сделать это, но он просто дает мне ошибку, что список неразрешимых типов:

 list1 = [  [0,  4,  2,  5,  0,  0],
  [4,  0,  0,  0,  6,  4],
  [2,  0,  0,  7,  0,  0],
  [5,  0,  7,  0,  5,  3],
  [0,  6,  0,  5,  0,  1],
  [0,  4,  0,  3,  1,  0],
]

g=['a','b','c','d', 'e','f']
dl = zip(list1, g)
dict(dl)
print dl

Ошибка:

   File "/Users/zakirtatari/Documents/da.py", line 19, in <module>
      dict(dl)
   TypeError: unhashable type: 'list'
1
compcrk 14 Дек 2015 в 17:48

4 ответа

Лучший ответ

Если вам не нужны ключи с нулевыми значениями, это должно сработать:

from string import ascii_lowercase as letters
dict(zip(letters, [dict(zip(letters, L)) for L in list1]))

Если вы хотите отфильтровать такие ключи, вы можете сделать:

dict(zip(letters,
         [dict((k, v) for k, v in zip(letters, L) if v) for L in list1]))
4
Eugene Yarmash 14 Дек 2015 в 15:32

Сначала я напишу две функции: одну преобразую список в словарь, получая ключи из ascii_lowercase, а другую - через словари и отфильтровываю пары ключ-значение, значения которых равны нулю.

from string import ascii_lowercase

def list_to_dict(in_list):
    return dict([(k, v) for k, v in zip(ascii_lowercase, in_list)])

def filter_dict(in_dict):
    return dict([(k, v) for k, v in in_dict.items() if v != 0])

Тогда вся логика вписывается в один оператор итератора списка:

list1 = list_to_dict([filter_dict(list_to_dict(x)) for x in list1 ])

Сначала просмотрите каждую «строку» и превратите их в словари, затем отфильтруйте словари по значениям, равным нулю.

Запустите ту же функцию для списка словарей и превратите их в пары ключ-значение.

Возможно, вы захотите использовать OrderedDict, если хотите сохранить порядок элементов.

1
Eugene Yarmash 14 Дек 2015 в 15:30

Я не уверен, что я сделал бы это на практике в одну строчку, но здесь все равно, используя словарь:

{key: {key2: value for key2, value in zip(g, row) if value != 0}
 for key, row in zip(g, list1)}
1
steinar 14 Дек 2015 в 15:00

Приведенное ниже решение выглядит некрасиво (и может быть предварительно проверено с помощью enumerate и zip), но, похоже, оно делает то, что вы хотите:

alphabet = "abcdefghijklmnopqrstuvwxyz"
list1 = [[0,4,2,5,0], [4, 0, 0, 0, 6]]

g = {}
for idx in range(len(list1)):
    g[alphabet[idx]] = {}
    for idx_2 in range(len(list1[idx])):
        if list1[idx][idx_2] != 0:
            g[alphabet[idx]][alphabet[idx_2]] = list1[idx][idx_2]
1
acdr 14 Дек 2015 в 14:57