Canonical conversion of dict of dicts to list of dicts

dn PythonList at DancesWithMice.info
Wed Mar 31 02:37:38 EDT 2021


On 31/03/2021 19.24, Loris Bennett wrote:
> dn <PythonList at DancesWithMice.info> writes:
> 
>> On 31/03/2021 01.22, Loris Bennett wrote:
>>> Jon Ribbens <jon+usenet at unequivocal.eu> writes:
>>>> On 2021-03-30, Loris Bennett <loris.bennett at fu-berlin.de> wrote:
>>>>> If I have dict of dicts, say
>>>>>
>>>>>   dod = {
>>>>>       "alice":
>>>>>       {
>>>>>           "lang": "python",
>>>>>           "level": "expert"
>>>>>       },
>>>>>       "bob":
>>>>>       {
>>>>>           "lang": "perl",
>>>>>           "level": "noob"
>>>>>       }
>>>>>   }
>>>>>
>>>>> is there a canonical, or more pythonic, way of converting the outer key
>>>>> to a value to get a list of dicts, e.g
>> ...
>>
>>>>>
>>>>> than just
>>>>>
>>>>>   lod = []
>>>>>   for name in dod:
>>>>>       d = dod[name]
>>>>>       d["name"] = name
>>>>>       lod.append(d)
>>
>>
>> Please be aware of the 'law of unintended consequences' - what
>> functional programmers call "side-effects"!
>>
>> At the end of the above code, not only has "lod" been created (per spec)
>> but "dod" is no longer what it once was.
>>
>> Thus, future code may not rely upon the (above) structure. Of course, if
>> by "convert" you mean transform, ie that "dod" will be del()[eted]
>> afterwards, such may be completely unimportant.
>>
>>
>> from pprint import pprint as pp
>> import copy
>>
>> dod = {
>>       "alice":
>>       {
>>           "lang": "python",
>>           "level": "expert"
>>       },
>>       "bob":
>>       {
>>           "lang": "perl",
>>           "level": "noob"
>>       }
>> }
>>
>> original = copy.deepcopy( dod )
>> lod = []
>> for name in dod:
>>     d = dod[name]
>>     d["name"] = name
>>     lod.append(d)
>>
>> print( original == dod )
>> pp(dod)
>> pp(original)
>>
>>
>> False
>> {'alice': {'lang': 'python', 'level': 'expert', 'name': 'alice'},
>>  'bob': {'lang': 'perl', 'level': 'noob', 'name': 'bob'}}
>> {'alice': {'lang': 'python', 'level': 'expert'},
>>  'bob': {'lang': 'perl', 'level': 'noob'}}
> 
> Thanks for pointing that out.  Coming from Perl that's something I need
> to watch out for.  So if I do
> 
>   $ a = ["alice", "bob", "carol"]
>   $ b = a
>   $ b[1] = "bert"
>   $ b
>   ['alice', 'bert', 'carol']
>   $ a
>   ['alice', 'bert', 'carol']
> 
> I see that changing one list changes the other because 'a' and 'b' are
> just bindings to the same object.  However, If I look at non-list
> variables:
> 
>    $ a = "bob"
>    $ b = a
>    $ b = "bert"
>    $ a
>   'bob'
> 
> that doesn't happen.  What's the rational for that and where can I find
> it in the Python documentation?

Good observation!
Important to differences.

Python offers mutable (can be changed) and immutable (can't) objects
(remember: 'everything is an object'):
https://docs.python.org/3/reference/datamodel.html?highlight=mutable%20data

PS this even applies when the two identifiers pointing at the same
object are argument(s) to a function!
-- 
Regards,
=dn


More information about the Python-list mailing list