python 3.x - returning a replaced field in a list of namedtuples in a namedtuple -


i have restaurant , dish type namedtuple defined below:

restaurant = namedtuple('restaurant', 'name cuisine phone menu') dish = namedtuple('dish', 'name price calories')  r1 = restaurant('thai dishes', 'thai', '334-4433', [dish('mee krob', 12.50, 500),                                                     dish('larb gai', 11.00, 450)]) 

i need change price of dish 2.50. have following code:

def restaurant_raise_prices(rest): result = [] item in rest:     dish in item.menu:         dish = dish._replace(price = dish.price + 2.50)         result.append(item) return result 

it replaces price field , returns dish namedtuple:

[dish(name='mee krob', price=15.0, calories=500), dish(name='larb gai', price=13.5, calories=450)] 

how can change code add restaurant well?

but returns dish. if wanted entire restaurant too? how can make change output is:

restaurant('thai dishes', 'thai', '334-4433', [dish(name='mee krob', price=15.0, calories=500), dish(name='larb gai', price=13.5, calories=450)]) 

named tuples first , foremost tuples, , such immutable. means cannot modify existing objects. if wanted change them, have create new tuples containing new values , replace references old tuple new tuple.

the code using not work that, since dish = dish._replace(…) replace value of dish new tuple, changing dish references not update reference exists within restaurant tuple. also, line result.append(item) being part of inner loop iterate on dishes, end multiple (unchanged!) copies of same restaurant tuple in result.

you change make work (btw. assuming pass single restaurant function—so need 1 loop dishes):

def restaurant_raise_prices (rest):     dishes = []     dish in rest.menu:         dishes.append(dish._replace(price=dish.price + 2.50))     rest = rest._replace(menu=dishes)     return rest 

this return new restaurant changed prices each dish (note r1 won’t reflect change):

>>> r1 restaurant(name='thai dishes', cuisine='thai', phone='334-4433', menu=[dish(name='mee krob', price=12.5, calories=500), dish(name='larb gai', price=11.0, calories=450)]) >>> restaurant_raise_prices(r1) restaurant(name='thai dishes', cuisine='thai', phone='334-4433', menu=[dish(name='mee krob', price=15.0, calories=500), dish(name='larb gai', price=13.5, calories=450)]) 

a cleaner way introduce proper types mutable, can make bit better. after all, restaurants objects can change: can modify menu time, without becoming new restaurant. makes sense have restaurants—as dishes—be mutable objects instead:

class restaurant:     def __init__ (self, name, cuisine, phone):         self.name = name         self.cuisine = cuisine         self.phone = phone         self.menu = []      def __str__ (self):         return '{} ({}) - {} ({} dishes)'.format(self.name, self.cuisine, self.phone, len(self.menu))  class dish:     def __init__ (self, name, price, calories):         self.name = name         self.price = price         self.calories = calories      def raise_price (self, amount):         self.price += amount      def __str__ (self):         return '{} (price: {}, calories: {})'.format(self.name, self.price, self.calories) 
>>> r1 = restaurant('thai dishes', 'thai', '334-4433') >>> r1.menu.append(dish('mee krob', 12.50, 500)) >>> r1.menu.append(dish('larb gai', 11.00, 450))  >>> print(r1) thai dishes (thai) - 334-4433 (2 dishes) >>> dish in r1.menu:         print(dish)  mee krob (price: 12.5, calories: 500) larb gai (price: 11.0, calories: 450)  >>> dish in r1.menu:         dish.raise_price(2.50)         print(dish)  mee krob (price: 15.0, calories: 500) larb gai (price: 13.5, calories: 450) 

Comments

Popular posts from this blog

qt - Using float or double for own QML classes -

Create Outlook appointment via C# .Net -

ios - Swift Array Resetting Itself -