python: итерация через словарь со значениями списка

Учитывая словарь списков, например

d = {'1':[11,12], '2':[21,21]} 

Что более питоновское или иное предпочтительнее:

 for k in d: for x in d[k]: # whatever with k, x 

или

 for k, dk in d.iteritems(): for x in dk: # whatever with k, x 

или есть что-то еще, чтобы рассмотреть?

EDIT, в случае, если список может быть полезен (например, стандартные dicts не сохраняют порядок), это может быть уместно, хотя оно намного медленнее.

 d2 = d.items() for k in d2: for x in d2[1]: # whatever with k, x 

    Вот тест скорости, почему бы и нет:

     import random numEntries = 1000000 d = dict(zip(range(numEntries), [random.sample(range(0, 100), 2) for x in range(numEntries)])) def m1(d): for k in d: for x in d[k]: pass def m2(d): for k, dk in d.iteritems(): for x in dk: pass import cProfile cProfile.run('m1(d)') print cProfile.run('m2(d)') # Ran 3 trials: # m1: 0.205, 0.194, 0.193: average 0.197 s # m2: 0.176, 0.166, 0.173: average 0.172 s # Method 1 takes 15% more time than method 2 

    Результат примера cProfile:

      3 function calls in 0.194 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.194 0.194 <string>:1(<module>) 1 0.194 0.194 0.194 0.194 stackoverflow.py:7(m1) 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 4 function calls in 0.179 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.179 0.179 <string>:1(<module>) 1 0.179 0.179 0.179 0.179 stackoverflow.py:12(m2) 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects} 1 0.000 0.000 0.000 0.000 {method 'iteritems' of 'dict' objects} 

    Мои результаты от кода Brionius:

      3 function calls in 0.173 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.173 0.173 <string>:1(<module>) 1 0.173 0.173 0.173 0.173 speed.py:5(m1) 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Prof iler' objects} 4 function calls in 0.185 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.185 0.185 <string>:1(<module>) 1 0.185 0.185 0.185 0.185 speed.py:10(m2) 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Prof iler' objects} 1 0.000 0.000 0.000 0.000 {method 'iteritems' of 'dict' obje cts} 

    Вот подход к пониманию списка. Вложенные …

     r = [[i for i in d[x]] for x in d.keys()] print r [[11, 12], [21, 21]] 

    Я рассмотрел несколько методов:

     import itertools COLORED_THINGS = {'blue': ['sky', 'jeans', 'powerline insert mode'], 'yellow': ['sun', 'banana', 'phone book/monitor stand'], 'red': ['blood', 'tomato', 'test failure']} def forloops(): """ Nested for loops. """ for color, things in COLORED_THINGS.items(): for thing in things: pass def iterator(): """ Use itertools and list comprehension to construct iterator. """ for color, thing in ( itertools.chain.from_iterable( [itertools.product((k,), v) for k, v in COLORED_THINGS.items()])): pass def iterator_gen(): """ Use itertools and generator to construct iterator. """ for color, thing in ( itertools.chain.from_iterable( (itertools.product((k,), v) for k, v in COLORED_THINGS.items()))): pass 

    Я использовал ipython и memory_profiler для проверки производительности:

     >>> %timeit forloops() 1000000 loops, best of 3: 1.31 µs per loop >>> %timeit iterator() 100000 loops, best of 3: 3.58 µs per loop >>> %timeit iterator_gen() 100000 loops, best of 3: 3.91 µs per loop >>> %memit -r 1000 forloops() peak memory: 35.79 MiB, increment: 0.02 MiB >>> %memit -r 1000 iterator() peak memory: 35.79 MiB, increment: 0.00 MiB >>> %memit -r 1000 iterator_gen() peak memory: 35.79 MiB, increment: 0.00 MiB 

    Как вы можете видеть, метод не имел заметного влияния на использование пиковой памяти, но вложенные for циклов были непревзойденными для скорости (не говоря уже о читаемости).