18 mapping names to sequence elements

Posted by cougar23 on Fri, 07 Jan 2022 23:10:32 +0100

Problem description

You have a piece of code that accesses elements in a list or tuple through subscripts, but this sometimes makes your code difficult to read, so you want to access elements by name.

Solution

collections. The namedtuple () function helps you solve this problem by using an ordinary tuple object. This function is actually a factory method that returns subclasses of standard tuple types in Python. You need to pass a type name and the fields you need to it, and then it will return a class. You can initialize this class, pass values for the fields you define, etc. For example:

from collections import namedtuple

Subscriber = namedtuple('Tester', ['addr', 'joined'])
sub = Subscriber('Abu11@cnblogs.com', '2022-01-07')
"""
sub = Tester(addr='Abu11@cnblogs.com', joined='2022-01-07')
sub.addr = Abu11@cnblogs.com
sub.joined = 2022-01-07
"""

Although the instance of namedtuple looks like an ordinary class instance, it is interchangeable with tuple types and supports all ordinary tuple operations, such as indexing and decompression. For example:

length = len(sub)
addr, joined = sub
"""
length = 2
addr = 'Abu11@cnblogs.com'
joined = '2022-01-07'
"""

One of the main uses of named tuples is to free your code from subscript operations. Therefore, if you manipulate elements in a tuple list by subscript, your code may make an error when you add a new column to the table. But if you use named tuples, you won't have this problem.
To illustrate this problem, the following code uses ordinary tuples:

def compute_cost(records):
	total = 0.0
	for rec in records:
		total += rec[1] * rec[2]
	return total

Subscript operations often obscure code and rely heavily on the structure of records. The following is the version using named tuples:

from collections import namedtuple

Stock = namedtuple('Stock', ['name', 'shares', 'price'])
def compute_cost(records):
	total = 0.0
	for rec in records:
		s = Stock(*rec)
		total += s.shares * s.price
	return total

discuss

Another function of named tuples is to replace dictionaries, because dictionary storage requires more memory space. If you need to build a very large data structure containing a dictionary, it is more efficient to use named tuples. Note, however, that a named tuple cannot be changed. For example:

s = Stock('A', 1, 22)  # Stock(name='A', shares=1, price=22)
s.shares = 7
"""
AttributeError: can't set attribute
"""

If you really need to change the value of the attribute, you can use the named tuple instance_ replace() method, which creates a new named tuple and replaces the corresponding field with a new value. For example:

s = s._replace(shares=7)
print(s)
"""Output results:
Stock(name='A', shares=7, price=22)
"""

_ Another useful feature of the replace() method is that it is a very convenient way to fill in data when your named tuple has optional or missing fields. You can create a prototype tuple with default values, and then use_ The replace() method creates a new instance whose value has been updated. For example:

from collections import namedtuple

Stock = namedtuple('Stock', ['name', 'shares', 'price', 'date', 'time'])
stock_instance = Stock('', 0, 0.0, None, None)


def dict_to_stock(s):
    return stock_instance._replace(**s)


if __name__ == '__main__':
    a = {'name': 'ACME', 'shares': 100, 'price': 123.45}
    print(dict_to_stock(a))
    b = {'name': 'ACME', 'shares': 100, 'price': 123.45, 'date': '12/17/2012'}
    print(dict_to_stock(b))
	
	"""Output results:
	Stock(name='ACME', shares=100, price=123.45, date=None, time=None)
	Stock(name='ACME', shares=100, price=123.45, date='12/17/2012', time=None)
	"""

Finally, if your goal is to define an efficient data structure that needs to update many instance properties, named tuples are not the best choice. At this point, you should consider defining an include__ slots__ Class of method (refer to subsection 8.4)

summary

This section describes collections Namedtuple () method, which can initialize a class and assign the value of a tuple to each field of the class in turn, so that the value can be accessed through the field. To some extent, it can replace the dictionary.

Topics: Python