This is part of a project that I've been working on for a bit now. I'm having a hard time synthesizing the mental pseudocode with something I can actually write, largely due to personal misconceptions about how stuff works.
I'm tracking inventory for an imaginary fruit stand, using the following class:
class Fruit(object)
def __init__(self,name,qty,price)
self.color = str(color)
self.qty = int(qty)
self.price = float(price)
def getName(self): return self.color
def getQty(self): return self.qty
def getPrice(self): return self.price
def description(self): return self.color,self.qty,self.price
Objects in this class end up getting imported as values for keys of a dictionary. There can be multiple values for each key, stored in a list, such that when the dictionary is printed, it returns something like this (with line breaks for readability:)
Lemon: [(Yellow, 5, 2.99)]
Apple: [(Red, 10, 0.99), (Green, 9, 0.69)]
Cherry: [(White, 2, 5.99),(Red, 5, 5.99)]
I am trying now to end up getting the sum value of all bits of fruit on my imaginary fruit stand. My original thought was just to treat each value as a list, iterate through the list until I hit an integer, multiply the integer by the float in the index right behind it, and then add that quantity to a variable that had a running total; then move on to keep looking for another integer. Which would work great, if "index 1" of list "Cherry" weren't (Red, 5, 5.99) rather than (2).
So, a couple of questions.
Every time I do something like this, where I have a dictonary with multiple values which are all class objects, each value is stored as a parenthetical (for lack of a better thing to call it.) Is that something that should be happening, or do I need to re-evaluate the way I am doing what I am doing, because I am causing that to happen?
If I don't need to re-evaluate my choices here, is there a way to break down the "parentheticals" (for lack of a better thing to call them immediately coming to mind) to be able to treat the whole thing as a list?
Is there a better way to do what I want to do that doesn't involve iterating through a list?
Thanks in advance. I have been fighting with various parts of this problem for a week.
Assuming a dictionary like this:
fruit_stand = {
"Lemon": [(Yellow, 5, 2.99)],
"Apple": [(Red, 10, 0.99), (Green, 9, 0.69)],
"Cherry": [(White, 2, 5.99),(Red, 5, 5.99)]
}
You can actually just iterate over the dictionary to get its keys:
for fruit_name in fruit_stand:
print fruit_name
# Lemon
# Apple
# Cherry
# NOTE: Order not guaranteed
# Cherry, Lemon, Apple are equally likely
You can then use the items
method of the dictionary to get a tuple (what you are calling a "parenthetical") of key
, value
pairs:
for fruit_name, fruits in fruit_stand.items():
print fruit_name, "=>", fruits
# Lemon => [(Yellow, 5, 2.99)]
# Apple => [(Red, 10, 0.99), (Green, 9, 0.69)]
# Cherry => [(White, 2, 5.99),(Red, 5, 5.99)]
list
s (that's the bracketed []
) are also iterable:
for fruit in [(White, 2, 5.99),(Red, 5, 5.99)]:
print fruit
# (White, 2, 5.99)
# (Red, 5, 5.99)
So we can work with each fruits
list to get access to our tuple
:
for fruit_name, fruit_list in fruit_stand.items():
# Ignore fruit_name and iterate over the fruits in fruit_list
for fruit in fruit_list:
print fruit
As we saw with items
we can unpack tuples into multiple values:
x, y = (1, 2)
print x
print y
# 1
# 2
So we can unpack each fruit
into its component parts:
for fruit_name, fruit_list in fruit_stand.items():
# Ignore fruit_name and iterate over the fruits in fruit_list
for color, quantity, cost in fruit_list:
print color, quantity, cost
And then getting the total isn't hard:
# We need to store our value somewhere
total_value = 0
for fruit_name, fruit_list in fruit_stand.items():
# Ignore fruit_name and iterate over the fruits in fruit_list
for color, quantity, cost in fruit_list:
total_value += (quantity * cost)
print total_value
All that being said, there are much clearer ways of doing things:
You could use list comprehension to simplify your for
loops:
for fruit_name in fruit_stand
operation(fruit_name)
can be translated to this list comprehension:
[operation(fruit_name) for fruit_name in fruit_stand]
Therefore, we can translate our nested for
loops into:
sum([cost * quantity \ # Final operation goes in front
for _, fruits in fruit_stand.items() \
for _, cost, quantity in fruits])
Because we don't actually need the list we can get rid of it and Python will create a generator for us instead:
sum(cost * quantity \ # Note the missing []
for _, fruits in fruit_stand.items() \
for _, cost, quantity in fruits)
You could add a __add__
method to Fruit
so that adding two sets of fruits together gives you the total cost of both sets of Fruit
(but you would probably want to create an intermediate data structure to do that, say Basket
so Fruit
didn't have to worry about quantity
which doesn't really belong to Fruit
, save in the sense that any instance of Fruit
has the intrinsic quantity 1. I'm omitting the code for this option because this answer is already far too long.
The word you're looking for is "tuple". These "parentheticals" are tuples.
One of Python's major strengths is its compact syntax for iterating over lists. You can calculate the sum of the prices of each fruit in a single line:
>>> fruit = [("Red", 10, 0.99), ("Green", 9, 0.69)]
>>> sum(qty * price for color, qty, price in fruit)
16.11
Breaking it down, the stuff inside of sum()
is called a generator expression. for color, qty, price in fruit
iterates over fruit
and unpacks the tuples into three named variables. These variables can then be used on the left-hand side of the for
. For each tuple in the fruit
list, the generator expression calculates qty * price
.
If you put this expression inside of square brackets it becomes a list comprehension and lets you see the calculated values.
>>> [qty * price for color, qty, price in fruit]
[9.9, 6.209999999999999]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With