6

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?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Kuzen
  • 950
  • 3
  • 10
  • 15
  • 1
    I am surprised to see this (simple) question has never been asked before on Stack Overflow... – Maxime Lorant May 21 '14 at 20:58
  • @MaximeLorant It had definitely been asked prior to this question, for example [here](https://stackoverflow.com/questions/6475314) in 2011. It comes up all the time. However, the version of the question I have been establishing as canonical is newer than this one. – Karl Knechtel Jul 30 '22 at 01:46

4 Answers4

9

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)
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.

Dekker1
  • 5,565
  • 25
  • 33
0

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)
merlin2011
  • 71,677
  • 44
  • 195
  • 329
  • still not following sorry, not sure what x^2 does either. – Kuzen May 21 '14 at 20:39
  • @githubphagocyte, Oops, I meant `**`. Fixing. – merlin2011 May 21 '14 at 20:57
  • @githubphagocyte, I just changed it to simple multiplication to avoid complications about operators, since that is not the point of the example. Thanks for pointing that out. I have been writing too much `latex` and `R`. – merlin2011 May 21 '14 at 20:59
0

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.

whereswalden
  • 4,819
  • 3
  • 27
  • 41