Help me understand Carly's list comprehension

I got list comprehension in general. I’m just not sure if I understood the expression used in the last list comprehension on the exercise.

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

I printed some lines to understand what was happening on the list code:

range_hairstyles = range(len(hairstyles))
print(range_hairstyles)
print(list(range_hairstyles))
print(hairstyles[7])

So, my question is:
The list use the expression hairstyle[i] . This means the loop will iterate on all hairstyle indices? Same for new_prices[i], or any list I want the loop iterate on all indices?
Also, is this used only for loops? Because i can print(hairstyles[7]) but not print(hairstyles[i])

Thanks, I hope you can understand. English its not my first lenguage.

Yes. [i] refers to the index position in each list. Maybe think of [i] as an empty variable, if that makes sense.
With print(hairstyles[7]) you’re referring to what is at index 7 in the list, so, yep, that item from the list will print.

1 Like

Technically I think you’re iterating on range(len(hairstyles))
You can do that print test though:

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

It turns cuts_under_30 into a list of None but it’ll show you what the comprehension is doing.

a_range = range(10) a_range_prices = [30 for i in range(len(a_range))] print_test = [print(a_range[i]) for i in range(len(a_range))] print(print_test)

Yes, range() in the list comprehension makes [i] go from index position 0 to -1, or, the len() of the new_prices list.

I see,

but what I wasn’t quite getting was to why use the expression at the beginning of the list comprehension with [i], or why use [i] at all inside a list comprehension.

cuts_under_30 = [hairstyles[i] for..., insted of just cuts_under_30 = [hairstyles for...

because in all the lessons before I didn’t seen it beeing use like this. The last exercise before Carly’s Clippers was like this:

single_digits = range(0,10)

cubes = [num ** 3 for num in single_digits]
print(cubes)

(Edit: And also I just understood, I can create a comprehension list with a temporary variable that its a list. Because in the example above was used num wich is not a declared variable before and its not a list.

I was assuming that it would always be like this.)

I think the purpose was so that you could use the same index to access both the hairstyles and new_costs lists such that each hairstyle was matched up to the correct pricing.

If you’d rather avoid the indexing here you could use zip to iterate through both lists at the same time, for example-

cuts_under_30 = [
    style
    for style, price in zip(hairstyles, new_prices)
    if price < 30
]
print(cuts_under_30)

It’s more of a style and readability question. Overly complex list comprehensions can be really difficult for others to read, sometimes it’s better to stick with a simpler option such as normal for loops or consider another route to solve this such as using enumerate or perhaps a function.

1 Like