-1
d = {'a' : 1, 'b' : 2, 'c' : 3}

for letter,number in d.items():
    print(letter, number)

Is this the same as...

for letter in d:
    print(letter)
    print(d[letter])

I know that the output is the same but I'm interested in what the items() function is doing and how it's actually getting the values, is it just getting it from the keys?

Ogen
  • 6,499
  • 7
  • 58
  • 124
  • 1
    Basically it will `zip` the `keys()` and the `values()` as an iterable of tuples. – Malik Brahimi May 19 '15 at 00:03
  • But dicts are naturally unordered, how are the mappings ensured to be correct. – Ogen May 19 '15 at 00:09
  • 1
    As you can see in the source [here](https://hg.python.org/cpython/file/tip/Objects/dictobject.c#l1691) It is deeply implemented in CPython and will **not** do `zip` over `keys` and `values` – Bhargav Rao May 19 '15 at 00:10
  • 1
    The dictionary itself may be unordered but the keys and values will be in the same order such that they correspond. – Malik Brahimi May 19 '15 at 00:10
  • @BhargavRao I don't really understand that CPython – Ogen May 19 '15 at 00:13
  • @Ogen One of the reasons why I did not add an answer :/ – Bhargav Rao May 19 '15 at 00:14
  • @BhargavRao Yes, technically the source does not contain a `zip` but it emulates one through the use of for loops indexing two iterables, no? – Malik Brahimi May 19 '15 at 00:15
  • 1
    @Malik Go through the 10 lines from [here](https://hg.python.org/cpython/file/tip/Objects/dictobject.c#l1735). You will understand it better. – Bhargav Rao May 19 '15 at 00:17
  • The Python language spec only guarantees that the order when iterating over a dict will be stable (i.e. iterating over the same dict twice gives the same order). Your code should not depend on any particular order though. You really don't need to know any implementation details beyond that. In particular, if you write something specific to the CPython implementation, then it won't work with Pypi, or other implementations. – smci May 19 '15 at 00:47

1 Answers1

3

In the C implementation inside the Python interpreter, dictionaries are implemented as hash tables. Due to hash collisions, it's possible for two keys to map to the same entry in the hash table, so each item must have its corresponding key and value (or, rather, pointers to these) stored in the hash table right there next to each other, so that the key can be compared to verify that the correct item has been found. Iterating over the items is thus just as straightforward as iterating over the keys or values alone. It's just a matter of which pieces are being returned. (This also explains why iterating over keys and values separately returns them in the same order; exactly the same data structure is being iterated over in both cases.)

The specifics apply only to the standard Python interpreter, CPython, but most hash table implementations operate similarly.

kindall
  • 178,883
  • 35
  • 278
  • 309
  • I believe that if no mutation takes place that the Python spec guarantees that `zip(d.keys(), d.values())` should always be the same as as `d.items()` (regardless of its implementation) – Jon Clements May 19 '15 at 00:29
  • 1
    That would constrain the implementation to something very like CPython's, then. :-) – kindall May 19 '15 at 00:30
  • I'm trying to find the evidence, but I'm fairly certain it's a guarantee of the behaviour of a `dict` regardless of how it's implemented – Jon Clements May 19 '15 at 00:32
  • 1
    Umm... probably need something better than http://stackoverflow.com/a/835111/ though – Jon Clements May 19 '15 at 00:37