use set notation for repr of dict_keys?

dn PythonList at DancesWithMice.info
Sat Feb 20 15:00:48 EST 2021


On 20/02/2021 20.25, Wolfgang Stöcher wrote:
> Having a dict like
>   d = {'one': 1, 'two': 2}
> the representation of its keys
>   repr(d.keys())
> gives
>   "dict_keys(['one', 'two'])"
> 
> But since the keys are unique, wouldn't a representation using the set
> notation
> be more intuitive, i.e. what about changing the output of
> dict_keys.__repr__ to
>     "dict_keys({'one', 'two'})"
> (using curly braces instead of brackets)


When considering the data-returned, the logic of formatting as a set
makes sense. So, why did the Python-gods decide otherwise?


Let's start by asking what it actually is:

>>> d = {'one': 1, 'two': 2}
>>> repr(d.keys())
"dict_keys(['one', 'two'])"
>>> k = d.keys()
>>> type( k )
<class 'dict_keys'>

So, the output is not a set (as you say) but nor (as
apparently-indicated by the square-brackets) is it actually a list!

Not much help there, then. So, let's use help() to see if that helps,
hah! (long listing, so not reproduced here). No joy there either.


Is it actually one of our 'standard' collections at all?

>>> k is dict
False
>>> k is list
False
>>> k is set
False
>>> k is tuple
False

OK, that makes reasonable sense. Perhaps dict_keys are a sub-class then?

>>> isinstance( k, dict )
False
>>> isinstance( k, list )
False
>>> isinstance( k, set )
False
>>> isinstance( k, tuple )
False

Still going 'nowhere' fast!

It is (apparently) reported as a list, and we'd like to think of it as a
set. So, compare help() output with the attributes of list and set
(and/or other collections).

There are considerable differences (again, not reproduced here due to
length).

However, still not revealing any answers!


If we de-construct the data contained in a dictionary, then as well as
the keys, we should consider the values:

>>> d
{'one': 1, 'two': 2}
>>> k = d.keys()
>>> k
dict_keys(['one', 'two'])
>>> v = d.values()
>>> v
dict_values([1, 2])

Hah, they are (apparently) considered a list as well, but have another
distinct type/are another custom-object.

Still not making progress though!


We've looked at the data/the output and found nothing much!

Now, let's totally invert our view of the matter: Instead of
deconstructing the original dictionary, consider the purpose of repr()?

<<<built-in function to compute the “official” string representation of
an object.>>> #repr

Thus, we should be able to take the output of repr() and re-create the
original object.

Because a dictionary consists of key-value pairs, we will need both
'sets' of components:

>>> new_d = dict( zip( k, v ) )
>>> new_d
{'one': 1, 'two': 2}

Ahah! Now, we realise that whereas a list-like #list data structure
maintains the sequence of its elements, a set #set is not required to do
so. Thus, if "k" were a set, what is produced on your machine may be
different to what happens on mine/no guarantees:

Possibly @Wolfgang's machine =
>>> k
{ 'one', 'two' }

Possibly @dn's machine =
>>> k
{ 'two', 'one' }

Thus no guarantee that when we try to re-combine keys and values they
would correspond correctly!

- and if we applied the same to data - even worse: combinatorial issue!


Web.Refs:
#repr:
https://docs.python.org/3/reference/datamodel.html#basic-customization
#list: and #set:
https://docs.python.org/3/reference/datamodel.html#the-standard-type-hierarchy
-- 
Regards,
=dn


More information about the Python-list mailing list