2

Here is my problem: I have a dict in python such as:

a = {1:[2, 3], 2:[1]}

I would like to output:

1, 2
1, 3
2, 1

what I am doing is

for i in a:
    for j in a[i]:
        print i, j 

so is there any easier way to do that avoiding two loops here or it is the easiest way already?

5
  • What you have is probably as clear as it gets. The only issue is that it doesn't produce the commas in the output, but that's trivial to fix. Commented Jan 20, 2013 at 16:58
  • It's not getting any simpler from the loops point of view, on the other hand, I'd rather write for i, vals in a.iteritems(): for j in vals... Commented Jan 20, 2013 at 17:01
  • 1
    You might want to switch to for i in sorted(a): -- right now your code doesn't necessarily give the results in increasing order of i. That may not matter, though. Commented Jan 20, 2013 at 17:01
  • @DSM: Wow. I just thought "What? Sorting a dictionary?", then I tried it, and now I've learned that sorted(mydict) gives me a sorted list of mydict's keys. Thanks a lot! Commented Jan 20, 2013 at 17:03
  • @TimPietzcker That's because the dictionary iterator returns the keys. i.e it is equivalent to : sorted(iter(mydict)). Commented Jan 20, 2013 at 17:06

3 Answers 3

3

The code you have is about as good as it gets. One minor improvement might be iterating over the dictionary's items in the outer loop, rather than doing indexing:

for i, lst in a.items() # use a.iteritems() in Python 2
    for j in lst:
        print("{}, {}".format(i, j))
Sign up to request clarification or add additional context in comments.

Comments

0

Couple of alternatives using list comprehensions, if you want to avoid explicit for loops.

# 1 method

# Python2.7
for key, value in a.iteritems():    # Use a.items() for python 3
    print "\n".join(["%d, %d" % (key, val) for val in value])

# 2 method - A more fancy way with list comprehensions

print "\n".join(["\n".join(["%d, %d" % (key, val) for val in value]) for key, value in a.iteritems()])

Both will output

1, 2
1, 3
2, 1

Comments

0

Remember in Python, Readability counts., so ideally @Blckknght's solution is what you should look forward, but just looking at your problem, technically as a POC, that you can rewrite your expression as a single loop, here is a solution.

But caveat, if you wan;t your code to be Readable, remember Explicit is better than implicit.

>>> def foo():
    return '\n'.join('{},{}'.format(*e) for e in chain(*(izip(cycle([k]),v) for k,v in a.items())))

>>> def bar():
    return '\n'.join("{},{}".format(i,j) for i in a for j in a[i])

>>> cProfile.run("foo()")
         20 function calls in 0.000 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.000    0.000 <pyshell#240>:1(foo)
        5    0.000    0.000    0.000    0.000 <pyshell#240>:2(<genexpr>)
        1    0.000    0.000    0.000    0.000 <string>:1(<module>)
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
       10    0.000    0.000    0.000    0.000 {method 'format' of 'str' objects}
        1    0.000    0.000    0.000    0.000 {method 'items' of 'dict' objects}
        1    0.000    0.000    0.000    0.000 {method 'join' of 'str' objects}


>>> cProfile.run("bar()")
         25 function calls in 0.000 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.000    0.000 <pyshell#242>:1(bar)
       11    0.000    0.000    0.000    0.000 <pyshell#242>:2(<genexpr>)
        1    0.000    0.000    0.000    0.000 <string>:1(<module>)
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
       10    0.000    0.000    0.000    0.000 {method 'format' of 'str' objects}
        1    0.000    0.000    0.000    0.000 {method 'join' of 'str' objects}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.