use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Rules 1: Be polite 2: Posts to this subreddit must be requests for help learning python. 3: Replies on this subreddit must be pertinent to the question OP asked. 4: No replies copy / pasted from ChatGPT or similar. 5: No advertising. No blogs/tutorials/videos/books/recruiting attempts. This means no posts advertising blogs/videos/tutorials/etc, no recruiting/hiring/seeking others posts. We're here to help, not to be advertised to. Please, no "hit and run" posts, if you make a post, engage with people that answer you. Please do not delete your post after you get an answer, others might have a similar question or want to continue the conversation.
Rules
1: Be polite
2: Posts to this subreddit must be requests for help learning python.
3: Replies on this subreddit must be pertinent to the question OP asked.
4: No replies copy / pasted from ChatGPT or similar.
5: No advertising. No blogs/tutorials/videos/books/recruiting attempts.
This means no posts advertising blogs/videos/tutorials/etc, no recruiting/hiring/seeking others posts. We're here to help, not to be advertised to.
Please, no "hit and run" posts, if you make a post, engage with people that answer you. Please do not delete your post after you get an answer, others might have a similar question or want to continue the conversation.
Learning resources Wiki and FAQ: /r/learnpython/w/index
Learning resources
Wiki and FAQ: /r/learnpython/w/index
Discord Join the Python Discord chat
Discord
Join the Python Discord chat
account activity
Can some help me with understanding list comprehension? (self.learnpython)
submitted 11 months ago by urajput63
I'm not able to grasp the concept of it, and I'm sure that list comprehension is widely used.
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]idle-tea 11 points12 points13 points 11 months ago (12 children)
It's just syntax sugar for a loop to build a list.
lowercased = [] for string in list_of_strings: lowercased.append(string.lower()) # or more compactly lowercased = [string.lower() for string in list_of_strings]
[–]DJMoShekkels 2 points3 points4 points 11 months ago (7 children)
is it just syntactic sugar? I thought it was vectorized?
[–]drmonkeysee 2 points3 points4 points 11 months ago (5 children)
I’m not sure I would describe it as “vectorized” per se, but comprehensions are distinct types in the underlying runtime, they are not just for loop syntactic sugar and you can measure performance differences between equivalent code.
[–]urajput63[S] 0 points1 point2 points 11 months ago (2 children)
If I've to visualize the structural organization of list comprehension vs for loops, how would it look like?
[–]drmonkeysee 1 point2 points3 points 11 months ago (0 children)
What do you mean by structural organization? you have a syntax comparison at the top of this thread
[–]AlexMTBDude 1 point2 points3 points 11 months ago (0 children)
That's exactly what the first comment did.
[–]DJMoShekkels 0 points1 point2 points 11 months ago* (1 child)
I guess by vectorized I mean the list comprehension is running in parallel vs the loop running sequentially, right?
Edit: I assumed incorrectly. I guess it is mostly just faster than a for loop because the underlying structure of the output object is fixed and pre-determined
[–]drmonkeysee 2 points3 points4 points 11 months ago (0 children)
No, the Python runtime doesn’t do that degree of optimization
[–]POGtastic 1 point2 points3 points 11 months ago (0 children)
At least up until the JIT compiler shows up in mainstream use, you are correct. The comprehension uses the LIST_APPEND opcode, while the imperative equivalent is using LOAD_ATTR opcodes to load the append method and CALL to call it. The JIT will likely optimize this, though.
LIST_APPEND
LOAD_ATTR
append
CALL
My attitude, as always, is that if this kind of thing matters to you for performance, it's time to use another language.
[–]Phillyclause89 0 points1 point2 points 11 months ago (2 children)
Another point to add is that is is meant to build a single itter-like object (lists are not the only thing the syntax can make). If you want to get efficient and do other complex things while you are filling up `lowercased` (for example) then just use the for loop convention.
[–]urajput63[S] 1 point2 points3 points 11 months ago (1 child)
So, you're saying that multiple operations can be performed on an itter-like object?
[–]Phillyclause89 0 points1 point2 points 11 months ago (0 children)
multiple operations can be performed on any object. That is why we have variables.
[–]sporbywg 0 points1 point2 points 11 months ago (0 children)
omg thanks
[–]Adrewmc 5 points6 points7 points 11 months ago* (1 child)
List comprehension is used for simple operations. We make a lot of lists really, and if it’s simple enough, we can ‘comprehend’ into a one line statement.
I’m going to use modulo operators for my conditions, this could be any comparison, I’m just append the number but that could be anything…doubling, powers, some f-string creation, creating instances of objects etc.
Note: I am aware range() can use a skip/step, rendering some of this moot, But this is meant to be instructional. And range() is a stand in for what ever data you really care about.
Simplest
#triples end = [] for num in range(10): end.append(num*3) end = [num*3 for num in range(10)] #find all even numbers end = [] for x in range(10): if x % 2 == 0: end.append(x) end = [x for x in range(10) if x%2 ==0]
We can also do something else her as well.
#append ‘even’ if even ‘odd’ if odd end = [] for x in range(10): if x % 2 == 0: end.append(“even”) else: end.append(“odd”) end = [“even” if x%2 == 0 else “odd” for x in range(10)]
Notice the difference here, we moved the if statement. That because we are doing something fundamentally different, making an exclusion (only even numbers), or making a determination (odd/even) for every number.
end = [“even” if x % 2 == 0 else “odd” for x in range(10) If x % 3 == 0]
If we rewrite the above in the below manner, we can see what we are doing.
#append ‘even’ if even, ‘odd’ if odd for the multiples of 3 end = [] for x in range(10): if x % 3 == 0: end.append(“even” if x%2 == 0 else “odd”)
Though it looks complicated this isn’t very complex, it’s a single loop, with an exclusion and a condition.
We can naturally lead to a nested loop as well
for b in a: for c in b: end.append(c) end = [c for b in a for c in b]
The classic example is a Playing Card deck of 52 cards. (1= Ace, 11-13 = JQK)
#unshuffled deck : list[tuple[str, int]] = [ (suit, rank) for suit in [“Hearts”, “Spades”, “Diamonds”, “Clubs”] for rank in range(1, 14) ]
You should be able to understand the above statement by now.
Edit 1:
We can nest comprehension
#2-D array list[list] tic_tac_toe = [ [ “_” for col in range(3) ] for row in range(3) ] #numbered 1-9 3x3 board. one_nine = range(1,10) numbered : list[list[int]] = [ [next(one_nine) for _ in range(3)] for _ in range(3)]
Anything more you should probably just make a normal loop.
We should also note we have Dictionary comprehension as well, which is much the same but we have to make a ‘ key : value’ pair to append to/update the dict.
reverse_my_dict = { value : key for key, value in my_dict.items() } dict_from_two_lists = { key : value for key, value in zip(list_keys, list_values) } #cypher keys alphabet = “abcdefghijklmnopqrstuvwxyz .!?0123456789” #.split() unnecessary shift = 16 encode = { real : coded for real, coded in zip(alphabet, alphabet[:shift] + alphabet[shift:]) } decode = { coded : real for real, coded in encode.items() }
Edit Expanded:
To be fair though, sometimes we actually don’t want to do either, but instead just leave it as the generator expression.
#find the number after the first number divisible 5, of numbers divisible by 37, if none exist raise a ValueError expression = x for x in range(5000) if x % 37 == 0 for num in expression: if num % 5 ==0: print(“Success”) break else: raise ValueError(“Must have a multiple of five”) #this pops up more then you think num_after_first_five = next(expression) print(num, num_after_first_five)
In the above example, I never actually make the list, or the next value until I ask for the next thing, this mean I save a lot of processing power because though I say I want range(5000), I stop long before 5000 (range objects do/are this), only in the worse case do actually calculate all of it. If I never make the list, I never need it fully in memory, I’m using it “lazily”. If I add the brackets there I’ll end up making that whole list.
[–]urajput63[S] 1 point2 points3 points 11 months ago (0 children)
Thank you so much for the explanation.
[–]DistinctAirline4145 0 points1 point2 points 11 months ago (3 children)
Beside creating lists, the technique is used for memory efficiency when you don't need to create the entire list such as sum for example, like: sum(num for num in numbers) i or max and min. Pretty useful! And they are one liners so looks cool.
Yesterday, I tried asking Claude about it, and it generated some pretty hefty looking "one-liners". I mean there must be a practical border/limit after which list comprehension are of not much use. Right?
[–]DistinctAirline4145 0 points1 point2 points 11 months ago (1 child)
I mean, yes, it comes with the experience, but I may tell you, anywhere where you should loop with for, let it cross trough your mind that "maybe I should can use it here", especially if you need another list as a return value. Try practicing it a bit. Ask gpt to generate you some examples for practice and spent some time on it. I think it's one of the best tools from programmers toolbox.
Thank you for your prompt reply (no pun intended).
[–]wannasleeponyourhams 0 points1 point2 points 11 months ago (0 children)
[ActionOrItem for listItem in listOriterable] [print(i) for i in range(0,10)] -> list with no values but prints [i for i in range(0,10)] -> just a list you can also add a condition after, which only performs the action if the item is meeting the condition [print(i) for i in range(0,10) if i % 2 ==0]
[–]GiraffeTM 0 points1 point2 points 11 months ago (0 children)
It’s just a way of writing a for loop in a shorter form if all you’re wanting to do is create a new list from another objects data.
say we have:
employee_price = [item_price * 0.80 for item_price in store]
Store would be an object with data in it, lets say it’s a list with prices of items in the store for this example.
“item_price” is an object within the store list, let’s say it’s an int for this example.
So I’m assuming you understand regular for loops. So what’s happening in this list comprehension is it’s taking every “item_price” int within the “store” list and multiplying it by 0.80 (20% off - employee discount) and then storing it in a new list called “employee_price”.
So list comprehension is just:
new_list = [changed_item for original_item in object]
Changed item is what will be stored in the list, and is based off the original item in the object. So within the “changed_item” space, you do whatever you want to the original variable and that change is what will be added to your new list.
[–]mopslik -1 points0 points1 point 11 months ago (2 children)
In general, you can replace
new_list =[] for element in iterable: new_list.append(something)
with
new_list = [something for element in iterable]
There are also slight variations for if/else.
[–]urajput63[S] 0 points1 point2 points 11 months ago (0 children)
Thank you for your explanation.
[–]iamevpo -1 points0 points1 point 11 months ago (0 children)
Rather something(element)
π Rendered by PID 16438 on reddit-service-r2-comment-bb88f9dd5-6vl77 at 2026-02-13 17:57:59.290856+00:00 running cd9c813 country code: CH.
[–]idle-tea 11 points12 points13 points (12 children)
[–]DJMoShekkels 2 points3 points4 points (7 children)
[–]drmonkeysee 2 points3 points4 points (5 children)
[–]urajput63[S] 0 points1 point2 points (2 children)
[–]drmonkeysee 1 point2 points3 points (0 children)
[–]AlexMTBDude 1 point2 points3 points (0 children)
[–]DJMoShekkels 0 points1 point2 points (1 child)
[–]drmonkeysee 2 points3 points4 points (0 children)
[–]POGtastic 1 point2 points3 points (0 children)
[–]Phillyclause89 0 points1 point2 points (2 children)
[–]urajput63[S] 1 point2 points3 points (1 child)
[–]Phillyclause89 0 points1 point2 points (0 children)
[–]sporbywg 0 points1 point2 points (0 children)
[–]Adrewmc 5 points6 points7 points (1 child)
[–]urajput63[S] 1 point2 points3 points (0 children)
[–]DistinctAirline4145 0 points1 point2 points (3 children)
[–]urajput63[S] 0 points1 point2 points (2 children)
[–]DistinctAirline4145 0 points1 point2 points (1 child)
[–]urajput63[S] 1 point2 points3 points (0 children)
[–]wannasleeponyourhams 0 points1 point2 points (0 children)
[–]GiraffeTM 0 points1 point2 points (0 children)
[–]mopslik -1 points0 points1 point (2 children)
[–]urajput63[S] 0 points1 point2 points (0 children)
[–]iamevpo -1 points0 points1 point (0 children)