Jojo Mojojo
Jojo Mojojo

Reputation: 55

iterating through dictionary with list as values in python

Say you have a dictionary as shown:

d = { 'a': ['s','b'], 'b': ['x1','y1','z1'] }

How could i produce the following output:

s, x1, b, y1, z1

Thanks

Upvotes: 1

Views: 4201

Answers (10)

Symon
Symon

Reputation: 2220

Here's an answer just as lazy, vague, and helpful as the OP's question.

Also, this smells like a homework question; if it is, it should be mentioned in the question.

import random
d = { 'a': ['s','b'], 'b': ['x1','y1','z1'] }
output = d['a']+d['b']
while output != ['s','x1','b','y1','z1']:
    random.shuffle(output)
print output

Please clarify your question if you want more helpful answers.

Upvotes: 1

DSM
DSM

Reputation: 353569

I can't believe there are so many answers to such a vague question! But then again I'm no better. :-) My first thought was to do this the way that had already been done using izip_longest, but I wasn't a fan of using None as a special value-- what if None was an element of the list, after all?

So instead, and assuming the "standard interpretation", how about:

>>> d = {'a': ['s', 'b'], 'b': ['x1', 'y1', 'z1']}
>>> [x[2] for x in sorted((i,k,v) for k in d for i,v in enumerate(d[k]))]
['s', 'x1', 'b', 'y1', 'z1']

This only requires that the keys be sortable, and if they're not then we're wrong anyway.

(Okay, to be perfectly honest, I first came up with zip(*sorted(chain(*(enumerate(d[k]) for k in sorted(d)))))[1], but I've been using itertools too much lately and that has too many parentheses for my liking.)

Upvotes: 3

jdi
jdi

Reputation: 92657

While Im not stoked about the appending and whatnot, this at least gets your exact result.

keys = sorted(d.keys())
total = max([len(v) for v in d.values()])
output = []
for i in xrange(total):
    for key in keys:
        try: output.append(d[key][i])
        except IndexError: pass

>>> output
['s', 'x1', 'b', 'y1', 'z1']

Upvotes: 5

Rob Wouters
Rob Wouters

Reputation: 16327

from itertools import izip_longest

d = { 'a': ['s','b'], 'b': ['x1','y1','z1'] }

print([i for t in izip_longest(*[d[k] for k in sorted(d)])
                  for i in t if i is not None])

(N.B. izip_longest was renamed to zip_longest in Python 3.)

Explanation:

izip_longest creates a tuple for the first elements, a tuple for the second elements etc. In this case [('s', 'x1'), ('b', 'y1'), (None, 'z1')]. After that it's simply creating a list while filtering out None.

You need izip_longest here instead of just zip otherwise the result will be [('s', 'x1'), ('b', 'y1')].

With intermediate steps:

sorted_lists = [d[k] for k in sorted(d)]
tuples = izip_longest(*sorted_lists)
result = [i for t in tuples for i in t if i is not None]
print(result)

Upvotes: 8

Rusty Rob
Rusty Rob

Reputation: 17213

>>> print ",".join([d['a'][0],d['b'][0],d['a'][1],d['b'][1],d['b'][2]])
s,x1,b,y1,z1

Can't help you much more without knowing more about your problem. Of course there are nice ways of outputting

If you're wanting order of keys and values, You could try something such as:

>>> tuples=[tuple([k]+d[k]) for k in d]
>>> tuples.sort()
>>> tuples
[('a', 's', 'b'), ('b', 'x1', 'y1', 'z1')]
>>> tuples_without_keys=[i[1:] for i in tuples]
>>> tuples_without_keys
[('s', 'b'), ('x1', 'y1', 'z1')]
>>> import itertools
>>> ans=itertools.izip_longest(*tuples_without_keys)
>>> ans=list(ans)
>>> ans
[('s', 'x1'), ('b', 'y1'), (None, 'z1')]
>>> [i for k in ans for i in k if i is not None]
['s', 'x1', 'b', 'y1', 'z1']

Upvotes: 1

shadyabhi
shadyabhi

Reputation: 17244

I think what he wants is first print all the first element of different values in dict & then second and so on until minimum of a list is reached. Then, he just prints the remaining.

d={'a':['s','b'],'b':['x1','y1','z1']}

min = len(d['a']) if (len(d['a']) < len(d['b']) ) else len(d['b'])

for i in range(0,min):
    p = d.keys()
    print d[p[0]][i], d[p[1]][i],

print d['b'][min:][0]

Upvotes: 4

RanRag
RanRag

Reputation: 49597

Your question is a little unclear to me but are you trying to achieve this

>>> d = { 'a': ['s','b'], 'b': ['x1','y1','z1'] }
>>> data = []
>>> for value in d.values():
...      for val in value:
...           data.append(val)
...
>>> data
['s', 'b', 'x1', 'y1', 'z1']

Upvotes: 2

Free Monica Cellio
Free Monica Cellio

Reputation: 2290

If I'm reading this correctly:

 result = []
 for x in d.values():
     for y in x:
          result.append(y)
 return result

Of course this assumes every value in d is iterable.

Upvotes: 1

user849425
user849425

Reputation:

result = []
d = { 'a':['s','b'], 'b':['x1','y1','z1'] }

result.append(d['a'][0])
result.append(d['b'][0])
result.append(d['a'][1])
result.append(d['b'][1])
result.append(d['b'][2])
print(result)

That will give you the answer you want. I'm not sure what you were looking for in particular.

Upvotes: 1

yedpodtrzitko
yedpodtrzitko

Reputation: 9359

maybe zip() http://docs.python.org/library/functions.html#zip can help you (I know it's not exactly you want, but maybe you'll find out how to get correct result:

>>> zip(*d.values())
[('s', 'x1'), ('b', 'y1')]

Upvotes: 2

Related Questions