Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 更改namedtuples列表的值_Python_List_Python 3.x_Tuples - Fatal编程技术网

Python 更改namedtuples列表的值

Python 更改namedtuples列表的值,python,list,python-3.x,tuples,Python,List,Python 3.x,Tuples,我有一个名为Books的命名夫妇列表,我正试图将price字段增加20%,这会改变Books的值。我试着做: 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), B

我有一个名为
Books
的命名夫妇列表,我正试图将
price
字段增加20%,这会改变
Books
的值。我试着做:

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)
但我一直得到:

 Traceback (most recent call last):
 print(item.price)
 AttributeError: 'float' object has no attribute 'price'
我知道我不能在namedtuple中设置字段。如何更新
价格

我试着把它变成一个函数:

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))
但我有一个错误,我说:

 rest.price = rest._replace(price = rest.price + newprice)
 AttributeError: can't set attribute

有人能告诉我为什么会发生这种情况吗?

命名元组是不可变的,因此您无法对它们进行操作

正确的做法: 如果您想要一些可更改的内容,可以使用

PS:如果没有安装recordtype,您可能需要安装它

糟糕的做法: 您还可以继续使用
namedtuple
和使用该方法


这看起来像是Python数据分析库的任务。做这种事情真的很容易:

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  

现在,这不是比在Python>=3.7中使用
namedtuple
s要好得多吗?

您可以使用decorator和新的变量注释功能来生成可变的记录类型:

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}")
输出:

New price for 'The Hunger Games' book is 7.66
New price for 'Harry Potter and the Sorcerer's Stone' book is 5.26

有没有一种方法可以使用_replace方法实现同样的效果?
pandas
相当重要-我会在遇到更严重的数据操作时使用它required@LeonSurrao我按照你的意愿用
\u replace()
方法更新了帖子。我不了解python社区。。。那
名为tuple.\u replace()
在函数式语言中非常惯用,为什么这里是“private”!?这真的不应该是一个坏方法,它肯定比转换为可变疯狂要好,而不是
rest.price=rest.\u replace(price=rest.price+newprice)
,do
rest=rest.\u replace(price=rest.price+newprice)
。请注意,
\u replace()
返回
namedtuple
@progo的新实例,
\u replace
实际上不是“私有”或内部的。基于doc:为了防止与字段名冲突,方法名和属性名以下划线开头。@Sait“假设元组中有数百万项。”这不是一种可能的情况,是吗?我希望我能给出更多的放弃投票——这保持了
namedtuple
的简单性,增加了类的易变性,并且不需要任何其他包装,无论是轻的还是重的。
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}")
New price for 'The Hunger Games' book is 7.66
New price for 'Harry Potter and the Sorcerer's Stone' book is 5.26