2

can anyone explain to me the why the design choice was made, that when calling __iter__ on a Python dictionary this should iterate over the key values only?

I might be biased by coming from C++, where - when iterating over a std::map - one gets std::map::value_type & [i.e. std::pair &] values.

I encountered this question when debugging strange program behavior, where I had a situtation similar to the following one:

def method(one=None, two=None, three=None):
    print('one: {one}, two: {two}, three: {three}'.format(one=one, two=two, three=three))
    return

if __name__ == '__main__':
    blub = {'one': 1, 'two': 2, 'three': 3}    
    method(*blub)
    exit(0)

with the following output

one: one, two: two, three: three

whereas I would have expected

one: 1, two: 2, three: 3

. My mistake was not to call method(**blub) obviously, but - again, I come from C++ - it took me some time to find this out.

Additionally I would have liked a warning, that passing a dict with one asterisk only may be undesired - but that's not how Python works, is it?

Might I have detected my error more easily using e.g. method(**kwargs)? I don't see how, but maybe someone can enlighten me here as well.

Thanks in advance

Johannes

  • 1
    Note, even if iterating over a dictionary did iterate over key-value pairs, `method(*blub)` would still not work the way you expdct it to. Try it with `method(*blub.items())` – juanpa.arrivillaga Jun 19 '22 at 11:28
  • "Additionally I would have liked a warning, that passing a dict with one asterisk only may be undesired - but that's not how Python works, is it?" Why would it warn you? – juanpa.arrivillaga Jun 19 '22 at 11:31
  • 2
    Actually in this case you could use keyword-only argument in the function to avoid that error, if it's desirable. – user202729 Jun 19 '22 at 11:32
  • 1
    what you are looking for is `dict.items()` which will return exactly what you are expecting from c++, as for the reason for this, i have seen in some video that it was really controversial, and they just decided that returning only keys is what most people want. – Ahmed AEK Jun 19 '22 at 11:35
  • if you don't like how this works, you can write your own dictionary class by subclassing `dict` class and have it work the way you want, additionally (and a lot more trickier) is that you can tamper with the `dict` class inside python to do what you want, but this is guaranteed to break any external dependency. – Ahmed AEK Jun 19 '22 at 11:41
  • Python gives `d.keys()`, `d.values()`, and `d.items()` to allow you to explicitly choose what to iterate over. `for x in d` or similar uses are just shortcuts, and "someone" decided to make them shortcuts for `keys()`, not for `values()` or `items()` (a decision which btw seems pretty natural to me, but this of course depends on your previous experiences). – gimix Jun 19 '22 at 12:59
  • Does this answer your question? [Iterating over dictionaries using 'for' loops](https://stackoverflow.com/questions/3294889/iterating-over-dictionaries-using-for-loops) – Davis Herring Jun 19 '22 at 21:02
  • @user202729 Keyword-only arguments look interesting. Thanks for that hint. – JohannesWilde Jun 21 '22 at 16:25
  • @AhmedAEK Would you maybe still know in what video you saw that controversery? That's exactly what I wanted to know with this question. And maybe just to clarify again: I don't want to oppose this decision or complain about undefined behavior [everything is documented well] - I just want to know what lead to this design decision. – JohannesWilde Jun 21 '22 at 16:29

0 Answers0