Search code examples
pythonlistclassdictionaryattributeerror

Beginner Python: AttributeError: 'list' object has no attribute


The error says:

AttributeError: 'list' object has no attribute 'cost' 

I am trying to get a simple profit calculation to work using the following class to handle a dictionary of bicycles:

class Bike(object):
    def __init__(self, name, weight, cost):
        self.name = name
        self.weight = weight
        self.cost = cost

bikes = {
    # Bike designed for children"
    "Trike": ["Trike", 20, 100],
    # Bike designed for everyone"
    "Kruzer": ["Kruzer", 50, 165]
    }

When I try to calculate profit with my for statement, I get the attribute error.

# Markup of 20% on all sales
margin = .2
# Revenue minus cost after sale
for bike in bikes.values():
    profit = bike.cost * margin

First, I don't know why it is referring to a list, and everything seems to be defined, no?


Solution

  • Consider:

    class Bike(object):
        def __init__(self, name, weight, cost):
            self.name = name
            self.weight = weight
            self.cost = cost
    
    bikes = {
        # Bike designed for children"
        "Trike": Bike("Trike", 20, 100),      # <--
        # Bike designed for everyone"
        "Kruzer": Bike("Kruzer", 50, 165),    # <--
        }
    
    # Markup of 20% on all sales
    margin = .2
    # Revenue minus cost after sale
    for bike in bikes.values():
        profit = bike.cost * margin
        print(profit)
    

    Output:

    33.0
    20.0
    

    The difference is that in your bikes dictionary, you're initializing the values as lists [...]. Instead, it looks like the rest of your code wants Bike instances. So create Bike instances: Bike(...).

    As for your error

    AttributeError: 'list' object has no attribute 'cost'
    

    this will occur when you try to call .cost on a list object. Pretty straightforward, but we can figure out what happened by looking at where you call .cost -- in this line:

    profit = bike.cost * margin
    

    This indicates that at least one bike (that is, a member of bikes.values() is a list). If you look at where you defined bikes you can see that the values were, in fact, lists. So this error makes sense.

    But since your class has a cost attribute, it looked like you were trying to use Bike instances as values, so I made that little change:

    [...] -> Bike(...)
    

    and you're all set.