Popping key causes dict derived from object to revert to object

Loris Bennett loris.bennett at fu-berlin.de
Fri Mar 22 03:58:28 EDT 2024


Mark Bourne <nntp.mbourne at spamgourmet.com> writes:

> Loris Bennett wrote:
>> Hi,
>> I am using SQLAlchemy to extract some rows from a table of 'events'.
>>  From the call to the DB I get a list of objects of the type
>>    sqlalchemy.orm.state.InstanceState
>> I would like to print these rows to the terminal using the
>> 'tabulate'
>> package, the documentation for which says
>>    The module provides just one function, tabulate, which takes a
>> list of
>>    lists or another tabular data type as the first argument, and outputs
>>    a nicely formatted plain-text table
>> So as I understand it, I need to convert the InstanceState-objects
>> to,
>> say, dicts, in order to print them.  However I also want to remove one
>> of the keys from the output and assumed I could just pop it off each
>> event dict, thus:
>>                event_dicts = [vars(e) for e in events]
>>      print(type(event_dicts[0]))
>>      event_dicts = [e.pop('_sa_instance_state', None) for e in event_dicts]
>>      print(type(event_dicts[0]))
>
> vars() returns the __dict__ attribute of the object.  It may not be a
> good idea to modify that dictionary directly (it will also affect the
> object), although it might be OK if you're not going to do anything
> else with the original objects.  To be safer, you could copy the event
> objects:
>     event_dicts = [dict(vars(e)) for e in events]
> or:
>     event_dicts = [vars(e).copy()]

Thanks for making this clear to me.  However, in the end I actually
decided to use the list comprehension without either 'dict()' or
'vars().  Instead I just select the keys I want and so don't need to pop
the unwanted key later and can simultaneously tweak the names of the
key for better printing to the terminal.

>> However, this prints
>>    <class 'dict'>
>>    <class 'sqlalchemy.orm.state.InstanceState'>
>> If I comment out the third line, which pops the unwanted key, I get
>>    <class 'dict'>
>>    <class 'dict'>
>> Why does popping one of the keys cause the elements of the list to
>> revert back to their original class?
>
> As Dieter pointed out, the main problem here is that pop() returns the
> value removed, not the dictionary with the rest of the values.  You
> probably want something more like:
>     for e in event_dicts:
>         del e['_sa_instance_state']
> (There's not really any point popping the value if you're not going to
> do anything with it - just delete the key from the dictionary)

Yes, I was mistakenly thinking that the popping the element would leave
me with the dict minus the popped key-value pair.  Seem like there is no
such function.

Cheers,

Loris
 
-- 
This signature is currently under constuction.


More information about the Python-list mailing list