Changing values of a list of namedtuples

后端 未结 3 1760
孤城傲影
孤城傲影 2020-12-28 12:31

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. I trie

相关标签:
3条回答
  • 2020-12-28 12:45

    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 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 namedtuples?

    0 讨论(0)
  • 2020-12-28 12:48

    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 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.

    Bad way of doing it:

    You may also keep using namedtuple with using the _replace() method.

    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)
    
    0 讨论(0)
  • 2020-12-28 12:51

    In Python >= 3.7 you can use dataclass decorator with the new variable annotations feature to produce mutable record types:

    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
    
    0 讨论(0)
提交回复
热议问题