[英]Changing values of a list of namedtuples
I have a list of namedtuples named Books
and am trying to increase the price
field by 20% which does change the value of Books
. 我有一个名为
Books
的名单元素列表,我试图将price
字段提高20%,这确实会改变Books
的价值。 I tried to do: 我试着这样做:
from collections import namedtuple
Book = namedtuple('Book', 'author title genre year price instock')
BSI = [
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 = item.price*1.10
print(item.price)
But I keep getting : 但我一直在:
Traceback (most recent call last):
print(item.price)
AttributeError: 'float' object has no attribute 'price'
I understand that I cannot set the fields in a namedtuple. 我知道我不能在namedtuple中设置字段。 How do I go about updating
price
? 我该如何更新
price
?
I tried to make it into a function: 我试着把它变成一个函数:
def restaurant_change_price(rest, newprice):
rest.price = rest._replace(price = rest.price + newprice)
return rest.price
print(restaurant_change_price(Restaurant("Taillevent", "French", "343-3434", "Escargots", 24.50), 25))
but I get an error with replace saying: 但我得到一个错误,替换说:
rest.price = rest._replace(price = rest.price + newprice)
AttributeError: can't set attribute
Can someone let me know why this is happening? 有人能告诉我为什么会这样吗?
Named tuples are immutable , so you cannot manipulate them. 命名元组是不可变的 ,因此您无法操纵它们。
If you want something mutable , you can use recordtype
. 如果你想要一些可变的东西,你可以使用
recordtype
。
from recordtype import recordtype
Book = 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. PS:如果你没有
pip install recordtype
你可能需要pip install recordtype
。
You may also keep using namedtuple
with using the _replace()
method. 您也可以继续使用
namedtuple
使用的_replace()
方法。
from collections import namedtuple
Book = 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: 在Python> = 3.7中,您可以使用带有新变量注释功能的数据类装饰器来生成可变记录类型:
from dataclasses import dataclass
@dataclass
class Book:
author: str
title: str
genre: str
year: int
price: float
instock: int
BSI = [
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.66
New 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 . 这看起来像是Python的数据分析库pandas的任务。 It's really, really easy to do this sort of thing:
做这种事真的很容易:
In [6]: import pandas as pd
In [7]: df = pd.DataFrame(BSI, columns=Book._fields)
In [8]: df
Out[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'] *= 100
In [10]: df
Out[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? 现在不是那么多,比使用
namedtuple
s更好吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.