Changing values of a list of namedtuples
Named tuples are immutable, so you cannot manipulate them.
Right way of doing it:
If you want something mutable, you can use recordtype
.
from recordtype import recordtypeBook = recordtype('Book', 'author title genre year price instock')books = [ Book('Suzane Collins','The Hunger Games', 'Fiction', 2008, 6.96, 20), Book('J.K. Rowling', "Harry Potter and the Sorcerer's Stone", 'Fantasy', 1997, 4.78, 12)]for book in books: book.price *= 1.1 print(book.price)
PS: You may need to pip install recordtype
if you don't have it installed.
Bad way of doing it:
You may also keep using namedtuple
with using the _replace()
method.
from collections import namedtupleBook = namedtuple('Book', 'author title genre year price instock')books = [ Book('Suzane Collins','The Hunger Games', 'Fiction', 2008, 6.96, 20), Book('J.K. Rowling', "Harry Potter and the Sorcerer's Stone", 'Fantasy', 1997, 4.78, 12)]for i in range(len(books)): books[i] = books[i]._replace(price = books[i].price*1.1) print(books[i].price)
In Python >= 3.7 you can use dataclass decorator with the new variable annotations feature to produce mutable record types:
from dataclasses import dataclass@dataclassclass Book: author: str title: str genre: str year: int price: float instock: intBSI = [ Book("Suzane Collins", "The Hunger Games", "Fiction", 2008, 6.96, 20), Book( "J.K. Rowling", "Harry Potter and the Sorcerer's Stone", "Fantasy", 1997, 4.78, 12, ),]for item in BSI: item.price *= 1.10 print(f"New price for '{item.title}' book is {item.price:,.2f}")
Output:
New price for 'The Hunger Games' book is 7.66New price for 'Harry Potter and the Sorcerer's Stone' book is 5.26
This looks like a task for Python's data analysis library, pandas. It's really, really easy to do this sort of thing:
In [6]: import pandas as pdIn [7]: df = pd.DataFrame(BSI, columns=Book._fields)In [8]: dfOut[8]: author title genre year \0 Suzane Collins The Hunger Games Fiction 2008 1 J.K. Rowling Harry Potter and the Sorcerers Stone Fantasy 1997 price instock 0 6.96 20 1 4.78 12 In [9]: df['price'] *= 100In [10]: dfOut[10]: author title genre year \0 Suzane Collins The Hunger Games Fiction 2008 1 J.K. Rowling Harry Potter and the Sorcerer's Stone Fantasy 1997 price instock 0 696 20 1 478 12
Now isn't that just much, much better than labouring with namedtuple
s?