[issue31086] Add namedattrgetter function which acts like attrgetter but uses namedtuple

Raymond Hettinger report at bugs.python.org
Tue Aug 1 02:01:15 EDT 2017


Raymond Hettinger added the comment:

Sorry Issac, but I'm going to decline this feature request.  I know you're enthusiastic about this or some other variation but I don't think it is worthy of becoming part of the standard library.  I do encourage you to post this somewhere as recipe (personally, I've used the ASPN cookbook to post my ideas) or as an offering on PyPI.

Reasons:

* The use cases are thin and likely to be uncommon.

* The recipe is short and doesn't add much value.

* The anonymous or autogenerated typename is unhelpful
  and the output doesn't look nice.

* It is already possible to combine a namedtuple with field
  extraction using a simple lambda.

* List comprehensions are clearer, easier, and more flexible
  for the task of extracting fields into a new named tuple.

* The combination of an anonymous or autogenerated typename
  along with automatic field renaming will likely cause
  more problems than it is worth.

* I don't expect this to mesh well with typing.NamedTuple
  and the needs of static typing tools

* Debugging may become more challenging with implicitly
  created named tuples that have autogenerated type names.


-- My experiments with the API ------------------------------

from collections import namedtuple
from operator import attrgetter
from pprint import pprint

def namedattrgetter (attr, *attrs):
    ag = attrgetter (attr, *attrs)
    if attrs:
        nt = namedtuple ('_', (attr,) + attrs, rename=True)
        return lambda obj: nt._make (ag (obj))
    else:
        return ag

Person = namedtuple('Person', ['fname', 'lname', 'age', 'email'])
FullName = namedtuple('FullName', ['lname', 'fname'])

people = [
	Person('tom', 'smith', 50, 'tsmith at example.com'),
	Person('sue', 'henry', 40, 'shenry at example.com'),
	Person('hank', 'jones', 30, 'hjones at example.com'),
	Person('meg', 'davis', 20, 'mdavis at example.com'),
]

# Proposed way
pprint(list(map(namedattrgetter('lname', 'fname'), people)))

# Existing way with two-steps (attrgetter followed by nt._make)
pprint(list(map(FullName._make, map(attrgetter(*FullName._fields), people))))

# Existing way using a lambda
pprint(list(map(lambda p: FullName(p.lname, p.fname), people)))

# Best way with a plain list comprehension
pprint([FullName(p.lname, p.fname) for p in people])

----------
resolution:  -> rejected
stage:  -> resolved
status: open -> closed

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue31086>
_______________________________________


More information about the Python-bugs-list mailing list