MegaS
MegaS

Reputation: 77

Python .values()[0] to pull out the first value of a list inside a dictionary

I'm trying to pull out the first value of each key but it seems to be iterating through the values, one by one but not exactly how I intended, it is doing:

e.g

    def budget_options(self):
        models = self.shop.get_bicycle_models()
        for model, price in zip(self.shop.models.keys(), self.shop.models.values()[0]):
            print(model, price)
            if price * self.margin <= self.budget:
                print("The {} is available for a price of ${:.2f}.".format(model, price * self.margin))


evans_cycles = BicycleShop("Evans Cycles", { "BMC Road Machine": [125, 2], "Cannondale Synapse": [275, 5], "Pinnacle Laterite": [450, 1], "Fuji Transonic": [625, 3], "Cervelo R2": [750, 5], "Specialized Roubaix": [999, 1] })

Returning

('BMC Road Machine', 125)
The BMC Road Machine is available for a price of $150.00.
('Cannondale Synapse', 2)
The Cannondale Synapse is available for a price of $2.40.

When it should be

('BMC Road Machine', 125)
The BMC Road Machine is available for a price of $150.00.
('Cannondale Synapse', 275)
The Cannondale Synapse is available for a price of $330.00.

I'm sorry if this is a stupid question but I am following the Thinkful Python course trying to learn but I'm stuck at the moment.

Upvotes: 1

Views: 9466

Answers (2)

PLPeeters
PLPeeters

Reputation: 1040

Your dictionary has no order. This means that when you call self.shop.models.keys() and self.shop.models.values(), the values won't necessarily get returned in the same order as the keys, leading to the unexpected behaviour you described.

This is where the dict.items() method comes in. What it does is simple:

Return a copy of the dictionary’s list of (key, value) pairs.

You can use it in your code as follows:

def budget_options(self):
    models = self.shop.get_bicycle_models()

    for model, prices in self.shop.models.items(): # Change this
        price = prices[0] # Add this

        print(model, price)

        if price * self.margin <= self.budget:
            print("The {} is available for a price of ${:.2f}.".format(model, price * self.

evans_cycles = BicycleShop("Evans Cycles", { "BMC Road Machine": [125, 2], "Cannondale Synapse": [275, 5], "Pinnacle Laterite": [450, 1], "Fuji Transonic": [625, 3], "Cervelo R2": [750, 5], "Specialized Roubaix": [999, 1] })

When using huge dictionaries, you should use dict.iteritems() instead. It works in exactly the same way but returns a generator instead of building the whole list of (key, value) pairs before returning it, reducing memory usage.

Upvotes: 2

Reti43
Reti43

Reputation: 9796

First of all, instead of zip(models.keys(), models.values()), do models.items(), which returns a tuple of (key, values).

for model, values in self.shop.models.items():
    price = values[0]  # this is the first item you wanted
    # do you stuff...

You might have a better description for values, but I don't know what the list [125, 2] represents, except from the fact that the first item is the price. But this is just nitpicking.

Upvotes: 0

Related Questions