dict: keys() and values() order guaranteed to be same?


H

Henrik Faber

Hi group,

I have a question of which I'm unsure if the specification guarantees
it. With an arbitrary dictionaty d, are d.keys() and d.values()
guaraneed to be in the same order? I.e. what I mean is:

# For all dictionaries d:
assert({ list(d.keys()): list(d.values()) for i in range(len(d)) }
== d)

I'm curious if it's allowed because in a special case it would make for
a nice shortcut and clean code. I think however that the implementation
may chose not to have them in the same order necessarily -- then I'd
obviously avoid relying on it.

Best regards,
Joe
 
Ad

Advertisements

P

Philipp Hagemeister

With an arbitrary dictionaty d, are d.keys() and d.values()
guaraneed to be in the same order?

Yes. From the documentation[1]:

If items(), keys(), values(), iteritems(), iterkeys(), and itervalues()
are called with no intervening modifications to the dictionary, the
lists will directly correspond.

In most cases, you should simply use items() though. Can you elaborate
on the use case for needing both keys() and values(), where items() is
not applicable?

- Philipp

[1] http://docs.python.org/library/stdtypes.html#dict.items


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (GNU/Linux)

iEYEAREKAAYFAlANODwACgkQ9eq1gvr7CFy3LgCgokRrZS4Hem35lHGB710qzmZp
UBYAoJ6Sn4KiJVu/ergs6UvgyW4eaBZ9
=Odni
-----END PGP SIGNATURE-----
 
S

Stefan Behnel

Henrik Faber, 23.07.2012 13:23:
I have a question of which I'm unsure if the specification guarantees
it. With an arbitrary dictionaty d, are d.keys() and d.values()
guaraneed to be in the same order? I.e. what I mean is:

# For all dictionaries d:
assert({ list(d.keys()): list(d.values()) for i in range(len(d)) }
== d)

I'm curious if it's allowed because in a special case it would make for
a nice shortcut and clean code. I think however that the implementation
may chose not to have them in the same order necessarily -- then I'd
obviously avoid relying on it.


You should.

Stefan
 
S

Stefan Behnel

Philipp Hagemeister, 23.07.2012 13:40:
With an arbitrary dictionaty d, are d.keys() and d.values()
guaraneed to be in the same order?

Yes. From the documentation[1]:

If items(), keys(), values(), iteritems(), iterkeys(), and itervalues()
are called with no intervening modifications to the dictionary, the
lists will directly correspond.

[1] http://docs.python.org/library/stdtypes.html#dict.items

Interesting. I wonder if other implementations like Jython and PyPy really
adhere to this official guarantee. At least Jython has the same paragraph
in its documentation and I would expect that PyPy follows it as well.

http://www.jython.org/docs/library/stdtypes.html#mapping-types-dict

Maybe this guarantee is just easy enough to build on the given
implementation details of a platform that it's a common property. Iteration
over data structures should tend to be deterministic, after all.

Stefan
 
H

Henrik Faber

With an arbitrary dictionaty d, are d.keys() and d.values()
guaraneed to be in the same order?

Yes. From the documentation[1]:

If items(), keys(), values(), iteritems(), iterkeys(), and itervalues()
are called with no intervening modifications to the dictionary, the
lists will directly correspond.

Ah, nice!
In most cases, you should simply use items() though. Can you elaborate
on the use case for needing both keys() and values(), where items() is
not applicable?

I need to parse and modify the keys of the dict and pass the keys as a
compound object to a function, which expects the values to be passed as
an argument list (weird, but can't change that). The order of arguments
is arbitrary (as the iteration over a dict is), but there has to be a
1-to-1 relation bewtween the compound object's key order and the
argument list's value order.

Best regards,
Henrik
 
S

Steven D'Aprano

Philipp Hagemeister, 23.07.2012 13:40:
With an arbitrary dictionaty d, are d.keys() and d.values() guaraneed
to be in the same order?

Yes. From the documentation[1]:

If items(), keys(), values(), iteritems(), iterkeys(), and itervalues()
are called with no intervening modifications to the dictionary, the
lists will directly correspond.

[1] http://docs.python.org/library/stdtypes.html#dict.items

Interesting. I wonder if other implementations like Jython and PyPy
really adhere to this official guarantee.

If they want to claim to be implementations of Python, as opposed to
merely some Python-like language with identical syntax but different
behaviour, then they better adhere to it. If they don't honour the
language promise, then they are buggy.


[...]
Maybe this guarantee is just easy enough to build on the given
implementation details of a platform that it's a common property.

Easy or hard, it is a promise of the language.

(Although if you think about the implementation of dicts as hash tables,
it does seem likely that it is trivial to enforce this -- one would have
to work *harder* to break that promise than to keep it.)

Iteration over data structures should tend to be deterministic, after
all.

Deterministic is not a very strong promise. The order of iteration of
dict.keys() is deterministic but not easily predictable, since it depends
on the history of the dictionary. The output of random.random() is
deterministic but (pseudo-)random.

Python's promise is much stronger than merely "deterministic": while it
does not promise what order the keys will be returned, it does promise
that whatever that order turns out to be, they will returned in the same
order as the matching values (unless you modify the dict while iterating).
 
Ad

Advertisements

C

Chris Angelico

(Although if you think about the implementation of dicts as hash tables,
it does seem likely that it is trivial to enforce this -- one would have
to work *harder* to break that promise than to keep it.)

However, it would be quite reasonable to implement a dict as a splay
tree, and have values() return them nearest-first. This would mean
that just reading from the dictionary could change the order of
values(), yet it wouldn't make the implementation non-conformant.

Of course, if I want splay tree semantics, I'd rather explicitly ask
for that. But it'd be legal.

ChrisA
 
E

Ethan Furman

Steven said:
Python's promise is much stronger than merely "deterministic": while it
does not promise what order the keys will be returned, it does promise
that whatever that order turns out to be, they will returned in the same
order as the matching values (unless you modify the dict while iterating).

or modify the dict between iterations.

~Ethan~
 
Ad

Advertisements

E

Ethan Furman

Chris said:
However, it would be quite reasonable to implement a dict as a splay
tree, and have values() return them nearest-first. This would mean
that just reading from the dictionary could change the order of
values(), yet it wouldn't make the implementation non-conformant.

Yes, it would. The docs say that .keys(), .values(), etc., will
maintain order unless the dict is modified in between calls.

~Ethan~
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top