Reputation: 5
Recently, I've found a code for developing a set of lists from a list, that code was written by user Mai, answering question but i have not understood it yet. Could somebody help me to understand it? And... is there a way to rewrite that code that be easier? The code is:
def even_divide(lst, num_piece=4):
return [
[lst[i] for i in range(len(lst)) if (i % num_piece) == r]
for r in range(num_piece)
]
Thanks!
Upvotes: 0
Views: 67
Reputation: 699
Could somebody help me to understand it?
Sure! It's a list comprehension. A list comprehension takes a list and does something to or with every element in that list. Let's say I want to multiply every element in my list by 2:
new_list = [element*2 for element in my_list]
What makes it a list comprehension is the bracket syntax. For those new to it, that's usually the part that takes a moment to get used to. With that said, I assume that is what is giving you difficulty in understanding the code in your question, as you have a list comprehension in a list comprehension. It might be difficult to understand now, but list comprehensions are a wonderful thing in python.
But, as this post mentions, there's a lot of discussions around list comprehension, lambda's, map, reduce, and filter. Ultimately, its up to you to decide what's best for your project. I'm not a fan of anything else but list comprehensions, so I use those religiously.
Based on the question you've linked, the list comprehension takes a 1d list of length x and turns it into a 2d list of (length x, width y). It's like numpy.reshape.
And... is there a way to rewrite that code [to] be easier?
I would not recommend it. List comprehensions are considered very pythonic and you will see them everywhere. Best to use them and get used to them.
Upvotes: 0
Reputation: 2895
It's pretty simple actually. Just follow through the values of the two loops:
Starting with the outer loop, r
would be 0
, then 1
, then 2
, etc. Let's look at the case for which r == 1
. When running through the different values of i
, (which would be 0, 1, 2, ... len(lst)
, the value of i % 4
, meaning the remainder of dividing i
by 4
, would be 0, 1, 2, 3, 0, 1, 2, 3, ...
. So the i % 4
would be equal to r
, for every 4 values of i
!
For our chosen r == 1
, that would mean we're choosing lst[1], lst[5], lst[9], ...
, etc.
And for r == 2
? You guessed it! You'd be picking up lst[2], lst[6], lst[10],...
.
So over all you'd get 4 lists, with non-overlapping elements of the original list, by just "jumping" 4 elements every time, but starting at different values.
Which naturally leads to the more simple solution:
def even_divide(lst, num_piece=4):
return [lst[r::num_piece] for r in range(num_piece)]
Upvotes: 1