Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #54760 > unrolled thread

Convert namedtuple to dictionary

Started bytripsvt@gmail.com
First post2013-09-25 15:45 -0700
Last post2013-09-26 08:47 +0200
Articles 10 — 8 participants

Back to article view | Back to comp.lang.python


Contents

  Convert namedtuple to dictionary tripsvt@gmail.com - 2013-09-25 15:45 -0700
    Re: Convert namedtuple to dictionary Tim Chase <python.list@tim.thechases.com> - 2013-09-25 18:41 -0500
      Re: Convert namedtuple to dictionary Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-09-26 01:08 +0000
        Re: Convert namedtuple to dictionary MRAB <python@mrabarnett.plus.com> - 2013-09-26 02:15 +0100
        Re: Convert namedtuple to dictionary Terry Reedy <tjreedy@udel.edu> - 2013-09-25 21:45 -0400
        Re: Convert namedtuple to dictionary Tim Chase <python.list@tim.thechases.com> - 2013-09-26 06:51 -0500
    Re: Convert namedtuple to dictionary MRAB <python@mrabarnett.plus.com> - 2013-09-26 00:52 +0100
    Re: Convert namedtuple to dictionary Ned Batchelder <ned@nedbatchelder.com> - 2013-09-25 20:15 -0400
    Re: Convert namedtuple to dictionary Steven D'Aprano <steve@pearwood.info> - 2013-09-26 03:48 +0000
    Re: Convert namedtuple to dictionary Peter Otten <__peter__@web.de> - 2013-09-26 08:47 +0200

#54760 — Convert namedtuple to dictionary

Fromtripsvt@gmail.com
Date2013-09-25 15:45 -0700
SubjectConvert namedtuple to dictionary
Message-ID<635a3b46-3150-409f-8a9d-002af18fb734@googlegroups.com>
Need suggestions. 

Say, I have a namedtuple like this:

{'a': brucelee(x=123, y=321), 'b': brucelee('x'=123, 'y'=321)

I need to convert it to:

{'a': {'x':123, 'y': 321},'b': {'x':123, 'y': 321}}

Follow-up question --

Which would be easier to work with if I had to later extract/manipulate the 'x', 'y' values? The format (dicts) above or a list of values like this:

{'a': ['x':123, 'y': 321],'b': ['x':123, 'y': 321]}

[toc] | [next] | [standalone]


#54762

FromTim Chase <python.list@tim.thechases.com>
Date2013-09-25 18:41 -0500
Message-ID<mailman.325.1380152379.18130.python-list@python.org>
In reply to#54760
On 2013-09-25 15:45, tripsvt@gmail.com wrote:
> Say, I have a namedtuple like this:
> 
> {'a': brucelee(x=123, y=321), 'b': brucelee('x'=123, 'y'=321)
> 
> I need to convert it to:
> 
> {'a': {'x':123, 'y': 321},'b': {'x':123, 'y': 321}}

While it uses the "private" member-variable "_fields", you can do

>>> brucelee = namedtuple("brucelee", "x y")
>>> d = {'a': brucelee(x=123,y=321), 'b': brucelee(x=234,y=432)}
>>> dict((k, dict((s, getattr(v, s)) for s in v._fields)) for k,v in
>>> d.iteritems())
{'a': {'y': 321, 'x': 123}, 'b': {'y': 432, 'x': 234}}

which can be made a bit more readable with a helper function:

>>> def dictify(some_named_tuple):
...     return dict((s, getattr(some_named_tuple, s)) for s in some_named_tuple._fields)
... 
>>> dict((k, dictify(v)) for k,v in d.iteritems())
{'a': {'y': 321, 'x': 123}, 'b': {'y': 432, 'x': 234}}

This would also make it easier to change/choose in the event
"_fields" ever changes.

-tkc



[toc] | [prev] | [next] | [standalone]


#54770

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-09-26 01:08 +0000
Message-ID<52438924$0$30000$c3e8da3$5496439d@news.astraweb.com>
In reply to#54762
On Wed, 25 Sep 2013 18:41:25 -0500, Tim Chase wrote about namedtuple:

> While it uses the "private" member-variable "_fields", you can do

It's not actually private!

namedtuple is documented as an exception to the rule that methods 
starting with a single leading underscore are private. Named tuples 
define three public methods and one data attribute. In order to avoid 
clashing with field names, they start with a single underscore, but they 
are documented as public:

_make
_asdict
_replace
_fields


http://docs.python.org/2/library/collections.html#namedtuple-factory-function-for-tuples-with-named-fields



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#54771

FromMRAB <python@mrabarnett.plus.com>
Date2013-09-26 02:15 +0100
Message-ID<mailman.331.1380158148.18130.python-list@python.org>
In reply to#54770
On 26/09/2013 02:08, Steven D'Aprano wrote:
> On Wed, 25 Sep 2013 18:41:25 -0500, Tim Chase wrote about namedtuple:
>
>> While it uses the "private" member-variable "_fields", you can do
>
> It's not actually private!
>
> namedtuple is documented as an exception to the rule that methods
> starting with a single leading underscore are private. Named tuples
> define three public methods and one data attribute. In order to avoid
> clashing with field names, they start with a single underscore, but they
> are documented as public:
>
> _make
> _asdict
> _replace
> _fields
>
>
> http://docs.python.org/2/library/collections.html#namedtuple-factory-function-for-tuples-with-named-fields
>
Wouldn't it have made more sense to have a trailing underscore instead?

[toc] | [prev] | [next] | [standalone]


#54774

FromTerry Reedy <tjreedy@udel.edu>
Date2013-09-25 21:45 -0400
Message-ID<mailman.333.1380159943.18130.python-list@python.org>
In reply to#54770
On 9/25/2013 9:15 PM, MRAB wrote:
> On 26/09/2013 02:08, Steven D'Aprano wrote:
>> On Wed, 25 Sep 2013 18:41:25 -0500, Tim Chase wrote about namedtuple:
>>
>>> While it uses the "private" member-variable "_fields", you can do
>>
>> It's not actually private!
>>
>> namedtuple is documented as an exception to the rule that methods
>> starting with a single leading underscore are private. Named tuples
>> define three public methods and one data attribute. In order to avoid
>> clashing with field names, they start with a single underscore, but they
>> are documented as public:
>>
>> _make
>> _asdict
>> _replace
>> _fields
>>
>>
>> http://docs.python.org/2/library/collections.html#namedtuple-factory-function-for-tuples-with-named-fields
>>
>>
> Wouldn't it have made more sense to have a trailing underscore instead?

Users might use such to avoid clashes with keywords and builtins: 
'print_', 'id_', 'as_', and will certainly sometimes use embedded _.

-- 
Terry Jan Reedy

[toc] | [prev] | [next] | [standalone]


#54815

FromTim Chase <python.list@tim.thechases.com>
Date2013-09-26 06:51 -0500
Message-ID<mailman.352.1380196196.18130.python-list@python.org>
In reply to#54770
On 2013-09-26 01:08, Steven D'Aprano wrote:
> On Wed, 25 Sep 2013 18:41:25 -0500, Tim Chase wrote about
> namedtuple:
> 
> > While it uses the "private" member-variable "_fields", you can do
> 
> It's not actually private!
> 
> namedtuple is documented as an exception to the rule that methods 
> starting with a single leading underscore are private. Named tuples 
> define three public methods and one data attribute. In order to
> avoid clashing with field names, they start with a single
> underscore, but they are documented as public:
> 
> _make
> _asdict
> _replace
> _fields

Well dang if "leading underscore suggests private/internal use"
convention got tossed out the window here :)

But indeed, they are in the docs, so (to the OP), use _asdict() and
make life easy.

-tkc


[toc] | [prev] | [next] | [standalone]


#54763

FromMRAB <python@mrabarnett.plus.com>
Date2013-09-26 00:52 +0100
Message-ID<mailman.326.1380153150.18130.python-list@python.org>
In reply to#54760
On 25/09/2013 23:45, tripsvt@gmail.com wrote:
> Need suggestions.
>
> Say, I have a namedtuple like this:
>
> {'a': brucelee(x=123, y=321), 'b': brucelee('x'=123, 'y'=321)

I assume you mean:

{'a': brucelee(x=123, y=321), 'b': brucelee(x=123, y=321)}

>
> I need to convert it to:
>
> {'a': {'x':123, 'y': 321},'b': {'x':123, 'y': 321}}
>
You can get the field names using ._fields and the values by using
list(...):

 >>> n = brucelee(x=123, y=321)
 >>> n._fields
('x', 'y')
 >>> list(n)
[123, 321]

Zip then together and pass the result to dict:

 >>> dict(zip(n._fields, list(n)))
{'x': 123, 'y': 321}

And, finally, putting that in a dict comprehension:

 >>> n = {'a': brucelee(x=123, y=321), 'b': brucelee(x=123, y=321)}
 >>> {k: dict(zip(v._fields, list(v))) for k, v in n.items()}
{'a': {'x': 123, 'y': 321}, 'b': {'x': 123, 'y': 321}}

> Follow-up question --
>
> Which would be easier to work with if I had to later extract/manipulate the 'x', 'y' values? The format (dicts) above or a list of values like this:
>
> {'a': ['x':123, 'y': 321],'b': ['x':123, 'y': 321]}
>
That's not valid Python!

[toc] | [prev] | [next] | [standalone]


#54768

FromNed Batchelder <ned@nedbatchelder.com>
Date2013-09-25 20:15 -0400
Message-ID<mailman.328.1380154894.18130.python-list@python.org>
In reply to#54760
On 9/25/13 6:45 PM, tripsvt@gmail.com wrote:
> Need suggestions.
>
> Say, I have a namedtuple like this:
>
> {'a': brucelee(x=123, y=321), 'b': brucelee('x'=123, 'y'=321)
>
> I need to convert it to:
>
> {'a': {'x':123, 'y': 321},'b': {'x':123, 'y': 321}}

Namedtuples have a ._asdict() method. You can convert your dictionary of 
namedtuples (let's call it tupledict) like this:

     dictdict = { k: nt._asdict() for k, nt in tupledict }

--Ned.
> Follow-up question --
>
> Which would be easier to work with if I had to later extract/manipulate the 'x', 'y' values? The format (dicts) above or a list of values like this:
>
> {'a': ['x':123, 'y': 321],'b': ['x':123, 'y': 321]}

[toc] | [prev] | [next] | [standalone]


#54777

FromSteven D'Aprano <steve@pearwood.info>
Date2013-09-26 03:48 +0000
Message-ID<5243ae75$0$2833$c3e8da3$76491128@news.astraweb.com>
In reply to#54760
On Wed, 25 Sep 2013 15:45:49 -0700, tripsvt wrote:

> Need suggestions.
> 
> Say, I have a namedtuple like this:
> 
> {'a': brucelee(x=123, y=321), 'b': brucelee('x'=123, 'y'=321)


That's not a namedtuple, that's a dict containing two namedtuples.


> I need to convert it to:
> 
> {'a': {'x':123, 'y': 321},'b': {'x':123, 'y': 321}}


Why bother? But if you must:

for key, value in some_dict.items():
    some_dict[key] = value._asdict()

ought to work.


> Follow-up question --
> 
> Which would be easier to work with if I had to later extract/manipulate
> the 'x', 'y' values? The format (dicts) above or a list of values like
> this:
> 
> {'a': ['x':123, 'y': 321],'b': ['x':123, 'y': 321]}

That's not legal Python.

The answer depends on what you mean by "extract/manipulate" the x and y 
fields. If all you are doing is looking them up, then a namedtuple is 
easiest, since that's what you've already got:

for value in some_dict.values():
    print(value.x)
    print(value.y)



But if you need to change those values, then a namedtuple is no good 
because it is immutable. In that case, you can either create a new 
namedtuple, or just use the dict-of-dicts version.



# Untested
for key, value in some_dict.items():
    kind = type(value)  # what sort of namedtuple is it?
    new = kind(value.x+1, value.y+2)
    some_dict[key] = new


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#54783

FromPeter Otten <__peter__@web.de>
Date2013-09-26 08:47 +0200
Message-ID<mailman.337.1380178007.18130.python-list@python.org>
In reply to#54760
tripsvt@gmail.com wrote:

> Need suggestions.
> 
> Say, I have a namedtuple like this:
> 
> {'a': brucelee(x=123, y=321), 'b': brucelee('x'=123, 'y'=321)
> 
> I need to convert it to:
> 
> {'a': {'x':123, 'y': 321},'b': {'x':123, 'y': 321}}
> 
> Follow-up question --
> 
> Which would be easier to work with if I had to later extract/manipulate
> the 'x', 'y' values? The format (dicts) above or a list of values like
> this:
> 
> {'a': ['x':123, 'y': 321],'b': ['x':123, 'y': 321]}

One more:

>>> from collections import namedtuple
>>> brucelee = namedtuple("brucelee", "x y")
>>> def to_dict(n):
...     return dict(zip(n._fields, n))
... 
>>> data = {'a': brucelee(x=123, y=321), 'b': brucelee(x=123, y=321)}
>>> {k: to_dict(v) for k, v in data.items()}
{'a': {'y': 321, 'x': 123}, 'b': {'y': 321, 'x': 123}}

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web