简体   繁体   中英

converting list of lists to dictionary

I have a list of list which is as follows:

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],
        ]

which I want to convert into a dictionary in the following way:

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}
 }

I have code the following to do that but it simply gives me an error that unhashable type list:

 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

the error is:

   File "/Users/zakirtatari/Documents/da.py", line 19, in <module>
      dict(dl)
   TypeError: unhashable type: 'list'

If you don't care about the keys with zero values, this should do the trick:

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

If you want to filter out such keys you can do:

dict(zip(letters,
         [dict((k, v) for k, v in zip(letters, L) if v) for L in list1]))

Below solution is kind of ugly (and could be prettified by using enumerate and zip), but it seems to do what you want it to do:

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]

I'm not sure I would do this in a one-liner in practice, but here is one all the same, using a dictionary comprehension:

{key: {key2: value for key2, value in zip(g, row) if value != 0}
 for key, row in zip(g, list1)}

First I would write two functions, one converting list into a dictionary, sourcing the keys from ascii_lowercase the other goes through dictionaries and filters out key-value pairs whose values are zero.

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])

Then all the logic fits into a single list iterator statement:

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

First, go through each 'row' and turn them into dictionaries, then filter the dictionaries on values that are equal to zero.

Run the same function against list of dictionaries and turn them into key-value pairs.

You might want to use OrderedDict if you want to preserve the order of elements.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM