# Carly's Clippers - list comprehension

Hi, I’m working on the Carly’s Clippers project (https://www.codecademy.com/courses/learn-python-3/projects/python-carlys-clippers) and I’m stuck in step 12.

Here’s my entire code, step 12 starting on line 25.

hairstyles = ["bouffant", "pixie", "dreadlocks", "crew", "bowl", "bob", "mohawk", "flattop"] prices = [30, 25, 40, 20, 20, 35, 50, 35] last_week = [2, 3, 5, 8, 4, 4, 6, 2] total_price = 0 for price in prices: total_price += price average_price = total_price / len(prices) print("Average Haircut Price:", average_price) new_prices = [price - 5 for price in prices] print("New Prices:", new_prices) total_revenue = 0 for i in range(len(hairstyles)): total_revenue += prices[i] * last_week[i] print("Total Revenue:", total_revenue) average_daily_revenue = total_revenue / 7 print("Average Daily Revenue:", average_daily_revenue) # My initial code: what's wrong here? cuts_under_30 = [hairstyles[i] for new_prices[i] in new_prices if new_prices[i] < 30] print(cuts_under_30) # Revised: cuts_under_30 = [hairstyles[i] for i in range(len(new_prices)) if new_prices[i] < 30] print(cuts_under_30)

I’m confused why my code here doesn’t work and prints out ‘flattop’ 4 times instead.

``````# My initial code: what's wrong here?
cuts_under_30 = [hairstyles[i] for new_prices[i] in new_prices if new_prices[i] < 30]
print(cuts_under_30)

# Revised:
cuts_under_30 = [hairstyles[i] for i in range(len(new_prices)) if new_prices[i] < 30]
print(cuts_under_30)
``````

Is it because I used the list `new_prices` and didn’t create a new list using `range()`?
Why should it be a problem?

This is occurring because of the way you are trying to use the variable ‘i’. Without any sort of logic to modify ‘i’ it will be a static number that has already been defined after the for loop on line 18.

1 Like

On line 15 when you print the new prices, you will see:

``````New Prices: [25, 20, 35, 15, 15, 30, 45, 30]
``````

As noted by ktsotras, when your loop (on line 18) finishes, then `i` will hold the last value assigned to it.
After the last iteration of the loop `for i in range(len(hairstyles))`, the last value assigned to `i` will be `7`.

``````# My initial code: what's wrong here?
cuts_under_30 = [hairstyles[i] for new_prices[i] in new_prices if new_prices[i] < 30]
print(cuts_under_30)
``````

In your list comprehension above, you are iterating over the `new_prices` list but the loop variable chosen by you is `new_prices[i]`.

In the first iteration, the first element of `new_prices` i.e. `25` will be assigned to `new_prices[i]` which is equivalent to the assignment `new_prices[7] = 25`. Then the if condition, checks whether `new_prices[7] < 30`. If so, `hairstyles[i]` i.e. `hairstyles[7]` is appended to the `cuts_under_30` list. There are four values in `new_prices` which are less than `30`, so `hairstyles[7]` i.e. the string `"flattop"` will be appended to `cuts_under_30` four times. Consequently, the output seen by you will be:

``````['flattop', 'flattop', 'flattop', 'flattop']
``````

To better understand what is going on, try turning your list comprehension into a for loop (with print statements for debugging):

``````print(new_prices)
cuts_under_30 = []
for new_prices[i] in new_prices:
print(new_prices)
if new_prices[i] < 30:
cuts_under_30.append(hairstyles[i])
print(cuts_under_30)

// Output
// new_prices before loop
[25, 20, 35, 15, 15, 30, 45, 30]

// new_prices during loop
// Note what is happening to new_prices[7]
[25, 20, 35, 15, 15, 30, 45, 25]
[25, 20, 35, 15, 15, 30, 45, 20]
[25, 20, 35, 15, 15, 30, 45, 35]
[25, 20, 35, 15, 15, 30, 45, 15]
[25, 20, 35, 15, 15, 30, 45, 15]
[25, 20, 35, 15, 15, 30, 45, 30]
[25, 20, 35, 15, 15, 30, 45, 45]
[25, 20, 35, 15, 15, 30, 45, 45]

// cuts_under_30 after loop
['flattop', 'flattop', 'flattop', 'flattop']
``````

Both your use of `i` and the choice of `new_prices[i]` as the loop variable is problematic.
You could use a variable such as

``````for price in new_prices:
``````

This will iterate over `new_prices` properly, but the problem is that the hairstyles are in a different list, and just the price won’t allow you to pick out the corresponding hairstyle.

Instead, looping over the index as you did in

``````# Revised:
cuts_under_30 = [hairstyles[i] for i in range(len(new_prices)) if new_prices[i] < 30]
``````

works. By looping over the index, you can use the same index `i` to pair the price with the corresponding hairstyle by targeting the correct elements from the `new_prices` and `hairstyles` lists respectively.

2 Likes