How does this "x for x in…" construct work?
Question:
Can someone please explain in detail the below type of for loop?
primes = [x for x in range(2, 50) if x not in noprimes]
or
le_list = [i for i in getfiles(path) if i != 'fred']
The bit i dont get is the i for i, or x for x. I do not understand what its actually saying.
variable for variable in a list if variable whatever.
I dont see why you need variable twice at the start. The for loop goes through each item in list anyway, how is it treated differently?
Answers:
It is a placeholder for a transformation of the element.
Suppose you wanted a list of primes multiplied by 2. Then you could replace the first x
with x*2
.
primes = [x*2 for x in range(2, 50) if x not in noprimes]
You write the following to say that you do not want a transformation, and just original x
.
primes = [x for x in range(2, 50) if x not in noprimes]
Another perspective: Consider the x
in the statement primes.append(x)
. That is the same as the first x
in the loop in your question. In fact, this is the exact same loop as the one above.
primes = []
for x in range(2,50):
if x not in noprimes:
primes.append(x)
Here is the other example, with x*2
.
primes = []
for x in range(2,50):
if x not in noprimes:
primes.append(x*2)
The good way to understand it is to read it a bit different. So if we take your piece of code:
primes = [x for x in range(2, 50) if x not in noprimes]
We can read is as:
Primes = All “x for” which “x in range(2,50)” but only “if x not in noprimes”
I hope this helps you understand the functionality better.
The reason for the apparently redundant extra mention of the variable x
when writing x for x
is that the first x
does not need to be x
. It just happens to be in the examples you give. Here are a few more examples which should clarify the difference between the first and second x
in your question:
ones = [1 for x in range(10)]
This simply gives a list of 10 ones, the same as [1] * 10
.
squares = [x*x for x in range(10)]
This gives x
squared for each x
in the specified range.
In your example, the second x
is the variable used by the for loop, and the first x
is simply an expression, which happens in your case to be just x
. The expression can be whatever you like, and does not need to be in terms of x
.
results = [expression for x in range(10)]
expression
can include anything you like – a string, a calculation, a function – whatever you choose. If the expression happens to be just x
then it looks unusual if you are not used to it, but it’s the same as the following:
results = []
for x in range(10):
results.append(expression)
This syntax is called a “comprehension” (e.g. list comprehension, dictionary comprehension, etc.). It’s a compact way of specifying the contents of the list/dictionary/other data structure programmatically. The Python docs explain it pretty well.
Can someone please explain in detail the below type of for loop?
primes = [x for x in range(2, 50) if x not in noprimes]
or
le_list = [i for i in getfiles(path) if i != 'fred']
The bit i dont get is the i for i, or x for x. I do not understand what its actually saying.
variable for variable in a list if variable whatever.
I dont see why you need variable twice at the start. The for loop goes through each item in list anyway, how is it treated differently?
It is a placeholder for a transformation of the element.
Suppose you wanted a list of primes multiplied by 2. Then you could replace the first x
with x*2
.
primes = [x*2 for x in range(2, 50) if x not in noprimes]
You write the following to say that you do not want a transformation, and just original x
.
primes = [x for x in range(2, 50) if x not in noprimes]
Another perspective: Consider the x
in the statement primes.append(x)
. That is the same as the first x
in the loop in your question. In fact, this is the exact same loop as the one above.
primes = []
for x in range(2,50):
if x not in noprimes:
primes.append(x)
Here is the other example, with x*2
.
primes = []
for x in range(2,50):
if x not in noprimes:
primes.append(x*2)
The good way to understand it is to read it a bit different. So if we take your piece of code:
primes = [x for x in range(2, 50) if x not in noprimes]
We can read is as:
Primes = All “x for” which “x in range(2,50)” but only “if x not in noprimes”
I hope this helps you understand the functionality better.
The reason for the apparently redundant extra mention of the variable x
when writing x for x
is that the first x
does not need to be x
. It just happens to be in the examples you give. Here are a few more examples which should clarify the difference between the first and second x
in your question:
ones = [1 for x in range(10)]
This simply gives a list of 10 ones, the same as [1] * 10
.
squares = [x*x for x in range(10)]
This gives x
squared for each x
in the specified range.
In your example, the second x
is the variable used by the for loop, and the first x
is simply an expression, which happens in your case to be just x
. The expression can be whatever you like, and does not need to be in terms of x
.
results = [expression for x in range(10)]
expression
can include anything you like – a string, a calculation, a function – whatever you choose. If the expression happens to be just x
then it looks unusual if you are not used to it, but it’s the same as the following:
results = []
for x in range(10):
results.append(expression)
This syntax is called a “comprehension” (e.g. list comprehension, dictionary comprehension, etc.). It’s a compact way of specifying the contents of the list/dictionary/other data structure programmatically. The Python docs explain it pretty well.