Reputation: 21
I have a dictionary where the values are lists of different lengths like so:
{"a":[1,2,3], "b":[4,3,5,6,7], "c":[1], "d":[2,5]}
I would like to convert it to a list of tuples for upload to a database:
[("a",1), ("a",2), ("a",3), ("b",4), ("b",3) ... ]
The most recent thing I have tried is:
lst = []
mydict = {"a":[1,2,3], "b":[4,3,5,6,7], "c":[1], "d":[2,5]}
for k in mydict.keys():
for i in range(len(mydict[k])):
count = 0
while count < i:
lst.append((k, mydict[k]))
count += 1
This does not work, but I can't tell why. Thanks for any help!
Upvotes: 1
Views: 150
Reputation: 310147
It feels like you're over-complicating it a bit...
It should only require 2 loops:
lst = []
for k, vals in mydict.items():
for value in vals:
lst.append((k, value))
The first loop is over the dictionary items, the inner loop is over the values list. For each value in the values list, just append a tuple that holds the key and the value to your resultant list.
And, FWIW, there are lots of other spellings here:
lst = []
for k, vals in mydict.items():
lst.extend((k, value) for value in vals)
Or even a 1-liner:
lst = [(k, value) for k, vals in mydict.items() for value in vals]
though I'm not a huge fan of the 1-line version...
As for why your version doesn't work, let's take a look and find out:
lst = []
mydict = {"a":[1,2,3], "b":[4,3,5,6,7], "c":[1], "d":[2,5]}
for k in mydict.keys():
for i in range(len(mydict[k])):
count = 0
while count < i:
lst.append((k, mydict[k]))
count += 1
The first thing that we see is you have an extra loop. For each key, you'll be hitting some of the values twice when you only want to hit them once. You could fix it by removing the loop over range(len(...))
:
lst = []
mydict = {"a":[1,2,3], "b":[4,3,5,6,7], "c":[1], "d":[2,5]}
for k in mydict.keys():
count = 0
while count < len(mydict[k]):
lst.append((k, mydict[k]))
count += 1
But, this is already a more verbose (and, IMHO, confusing) way to write it out than the options I've provided above.
Upvotes: 4
Reputation: 23773
Using itertools and zip:
import itertools
d = {"a":[1,2,3], "b":[4,3,5,6,7], "c":[1], "d":[2,5]}
result = []
for k, v in d.items():
result.extend(zip(itertools.cycle(k), v))
or:
for k, v in d.items():
result.extend(itertools.izip(itertools.cycle(k), v))
itertools.repeat could also be used in place of itertools.cycle.
Upvotes: 0
Reputation: 41119
new_list = []
for key, values in mydict.items():
for val in values:
new_list.append((key, val))
Upvotes: 0
Reputation: 7913
You should avoid for loops in python where possible, its very inefficient. Use list comprehension as the most pythonic way to do this. stack is the name of the dict:
[(i,x) for x in stack[i] for i in stack.keys()]
Upvotes: 0