Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NamedTuple declaration and use in a single line

I would like to store a dimension namedtuple (x, y). I will only need this once in my entire program.

I could do:

Dimension = namedtuple('Dimension', ['x', 'y'])
dim = Dimension(2, 3)

but, since I'm sure this is the only Dimension I will need in the entire program, I was wondering if I could make this into one-liner that returns an object whose properties I can access like dim.x and dim.y?

like image 808
Juicy Avatar asked Oct 16 '14 12:10

Juicy


People also ask

What is the use of Namedtuple?

Python's namedtuple() is a factory function available in collections . It allows you to create tuple subclasses with named fields. You can access the values in a given named tuple using the dot notation and the field names, like in obj.

Can you modify a Namedtuple?

Since a named tuple is a tuple, and tuples are immutable, it is impossible to change the value of a field. In this case, we have to use another private method _replace() to replace values of the field. The _replace() method will return a new named tuple.

What does Namedtuple on a collection type return?

NamedTuple can return the values with keys as OrderedDict type object. To make it OrderedDict, we have to use the _asdict() method.

What type is a Namedtuple?

Named tuple container datatype is an alternative to the built-in tuple . This extension type enhances standard tuples so that their elements can be accessed by both their attribute name and the positional index. Named tuples are available in Python's standard library collections module under the namedtuple utility.


2 Answers

I've come across this issue myself a lot; what would be great is if the Python standard library had the following convenience function built in to the collections module. But in lieu of that, you can always define this yourself locally:

def make_namedtuple(class_name, **fields):
    return namedtuple(class_name, fields)(*fields.values())

With this you could instantiate a new, single-use namedtuple class for a single instance like so:

dim = make_namedtuple('Dimension', x=2, y=3)

This works for Python 3.6+[1].

[1] the **fields' order is not maintained on Python versions <3.6 (in other words, pre-PEP 468). You can still use the function, but it kind of defeats the purpose of having a class that unpacks like a tuple, imo...

like image 164
CrepeGoat Avatar answered Oct 24 '22 02:10

CrepeGoat


There is no need for the temporary name Dimension:

dim = namedtuple('Dimension', ['x', 'y'])(2, 3)

Alternatively, you can use the three-argument form of type to create a new class and create an instance of it:

dim = type('Dimension', (object,), {'x': 2, 'y': 3})()

This object will use more memory but, unlike the namedtuple, will be mutable (this may or may not be a good thing for your use cases). It also saves an import.

like image 25
jonrsharpe Avatar answered Oct 24 '22 03:10

jonrsharpe