slightlyconfused
slightlyconfused

Reputation: 21

Convert nested list to dictionary

My nested list that I’m trying to convert into a dictionary looks like this:

my_dict = {}
book_ratings = [["Ben"],["5", "0", "1", "4"], ["Sally"],["0", "7", "3", "3"]]

I’m trying to return names ["Ben"], ["Sally"] as the keys and the ratings ["5","0","1","4"], ["0","7","3","3"] as the values.

Hoping for the output:

 {"Ben": ["5," "0", "1", "4"], "Sally": ["0", "7", "3", "3"]}

Upvotes: 0

Views: 2831

Answers (6)

superb rain
superb rain

Reputation: 5531

Simple dict comp:

>>> it = iter(book_ratings)
>>> {k: next(it) for k, in it}
{'Ben': ['5', '0', '1', '4'], 'Sally': ['0', '7', '3', '3']}

Benchmark with the accepted answer's solutions (f1 and f2) and mine (f3), three rounds, numbers are times in seconds so lower=faster:

2.31 f1
2.08 f2
1.39 f3

2.30 f1
2.03 f2
1.34 f3

2.30 f1
2.08 f2
1.31 f3

Benchmark code:

from timeit import repeat

book_ratings = []
for i in range(1000):
    book_ratings += [["Ben" + str(i)],["5", "0", "1", "4"]]    

def f1():
    i = iter(book_ratings)
    return dict((a[0], b) for a, b in zip(i, i))

def f2():
    return dict((a, b) for (a,), b in zip(book_ratings[::2], book_ratings[1::2]))

def f3():
    it = iter(book_ratings)
    return {k: next(it) for k, in it}

for _ in range(3):
    for f in f1, f2, f3:
        t = min(repeat(f, number=10000))
        print('%.2f' % t, f.__name__)
    print()

Upvotes: 7

Mladen Milosavljevic
Mladen Milosavljevic

Reputation: 1810

one more solution, may be simpler for beginners

my_dict =  {}
book_ratings = [['Ben'],[5, 0, 1, 4], ['Sally'],[0, 7, 3, 3]]
for i, book in enumerate(book_ratings):
    if (i==0) or (i%2==0):
        try:
            my_dict[book[0]] = book_ratings[i+1]
        except:
            pass
        
print(my_dict)

prints

  {'Ben': [5, 0, 1, 4], 'Sally': [0, 7, 3, 3]}
    

Upvotes: 0

PApostol
PApostol

Reputation: 2302

Maybe something like this:

my_dict = {}
book_ratings = [['Ben'],['5', '0', '1', '4'], ['Sally'],['0', '7', '3', '3']]

i=0
while i<len(book_ratings):
  if not book_ratings[i][0].isnumeric():
    my_dict[book_ratings[i][0]] = book_ratings[i+1]
    i+=2
  else:
    i+=1

print(my_dict)

Output:

{'Ben': ['5', '0', '1', '4'], 'Sally': ['0', '7', '3', '3']}

Upvotes: 0

Jab
Jab

Reputation: 27515

You can use iter and some zip magic to get every other key. But since your keys are in lists and you just want the single value from them you'll need to use a dict comprehension:

book_ratings = [["Ben"],["5", "0", "1", "4"], ["Sally"],["0", "7", "3", "3"]]
my_dict = {k[0]: v for k, v in zip(*([iter(book_ratings)]*2))}

{'Ben': ['5', '0', '1', '4'], 'Sally': ['0', '7', '3', '3']}

Upvotes: 2

Celius Stingher
Celius Stingher

Reputation: 18377

You can do it with dict comprehensions without the need to define an empty dict:

book_ratings = [["Ben"],["5", "0", "1", "4"], ["Sally"],["0", "7", "3", "3"]]
new_dict = {book_ratings[i][0]:book_ratings[i+1] for i in range(0,len(book_ratings),2)}
new_dict

Output:

{'Ben': ['5', '0', '1', '4'], 'Sally': ['0', '7', '3', '3']}

Upvotes: 1

Andrej Kesely
Andrej Kesely

Reputation: 195613

If the structure of book_ratings is Name, List, Name, List, ... you can use this example to construct the dictionary:

book_ratings = [["Ben"],["5", "0", "1", "4"], ["Sally"],["0", "7", "3", "3"]]

i = iter(book_ratings)
my_dict = dict((a[0], b) for a, b in zip(i, i))

print(my_dict)

Prints:

{'Ben': ['5', '0', '1', '4'], 'Sally': ['0', '7', '3', '3']}

Or:

my_dict = dict((a, b) for (a,), b in zip(book_ratings[::2], book_ratings[1::2]))

Upvotes: 2

Related Questions