# A little help with List Comprehension

• (2 Pages)
• 1
• 2

## 15 Replies - 1801 Views - Last Post: 16 October 2017 - 03:45 AMRate Topic: //<![CDATA[ rating = new ipb.rating( 'topic_rate_', { url: 'https://www.dreamincode.net/forums/index.php?app=forums&module=ajax&section=topics&do=rateTopic&t=357825&amp;s=2b62ba3d0072e93113a634c9c7e63585&md5check=' + ipb.vars['secure_hash'], cur_rating: 0, rated: 0, allow_rate: 0, multi_rate: 1, show_rate_text: true } ); //]]>

### #1 CyberPat

Reputation: 1
• Posts: 28
• Joined: 25-September 14

# A little help with List Comprehension

Posted 12 November 2014 - 03:07 AM

I know the concept.But my problem is i'm not so familiar with it.Like, from what i read, the syntax is :

[Y for x in LIST]

Where Y is commonly referred to as output function, x is variable and list is considered a set input.Now my question was,how does the following code work :

[x for x in range(51)

What does the first x do here?If it was x * 2, all of the numbers would be multiplied by 2.But when x is alone(no expression after it), what does it do?

I would gladly appreciate anyone who could be kind and enlighten me.Thank you so much.

Is This A Good Question/Topic? 0

## Replies To: A little help with List Comprehension

### #2 Peter O

• D.I.C Regular

Reputation: 128
• Posts: 300
• Joined: 19-October 13

## Re: A little help with List Comprehension

Posted 12 November 2014 - 03:28 AM

```[x for x in range(51)]
^ ^
| |
| For each x in range(51) ...
|
... output x.
```

So in other words this will output the same as range(51).

### #3 andrewsw

• RequestedRangeNotSatisfiable

Reputation: 6552
• Posts: 26,566
• Joined: 12-December 12

## Re: A little help with List Comprehension

Posted 12 November 2014 - 04:12 AM

The first statement won't work. Try:
```print([y for x in range(51)])
```

Quote

NameError: global name 'y' is not defined

```print([x for x in range(51)])
```

will work, as will
```print([x*2 for x in range(51)])
```

so the first part - the output - is an expression based on the generated output of the list on the right.

http://www.pythonfor...sions-in-python

### #4 jon.kiparsky

• Beginner

Reputation: 11072
• Posts: 18,910
• Joined: 19-March 11

## Re: A little help with List Comprehension

Posted 12 November 2014 - 08:48 AM

andrewsw, on 12 November 2014 - 06:12 AM, said:

The first statement won't work. Try:
```print([y for x in range(51)])
```

Quote

NameError: global name 'y' is not defined

```print([x for x in range(51)])
```

will work, as will
```print([x*2 for x in range(51)])
```

so the first part - the output - is an expression based on the generated output of the list on the right.

http://www.pythonfor...sions-in-python

Perhaps the OP meant Y to be "some function producing output"? In that case, the resulting list would be "whatever the output of Y was, 51 times". For example:

```>>> def y ():
...   return "Y output"
...
>>> [y() for x in range(10)]
['Y output', 'Y output', 'Y output', 'Y output', 'Y output', 'Y output', 'Y output', 'Y output', 'Y output', 'Y output']
>>>

```

or:

```>>> def y ():
...   return x * x
...
>>> [y() for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>>
```

In any case, probably the easiest way to understand the list comprehension is to unroll it into the notionally equivalent loop:

```[x for x in range (10)]
```

is equivalent to

```l = []
for x in range (10):
l.append(x)

```

So if you can reason about a loop, you can reason about a list comprehension.

### #5 andrewsw

• RequestedRangeNotSatisfiable

Reputation: 6552
• Posts: 26,566
• Joined: 12-December 12

## Re: A little help with List Comprehension

Posted 12 November 2014 - 10:16 AM

Jon's second example should be:
```def y(x):
return x * x
print([y(x) for x in range(10)])
```

### #6 jon.kiparsky

• Beginner

Reputation: 11072
• Posts: 18,910
• Joined: 19-March 11

## Re: A little help with List Comprehension

Posted 12 November 2014 - 10:34 AM

andrewsw, on 12 November 2014 - 12:16 PM, said:

Jon's second example should be:
```def y(x):
return x * x
print([y(x) for x in range(10)])
```

Why would I need the print statement? As for the x parameter on the y function, it's actually not required here: that's the point of the example.

### #7 andrewsw

• RequestedRangeNotSatisfiable

Reputation: 6552
• Posts: 26,566
• Joined: 12-December 12

## Re: A little help with List Comprehension

Posted 12 November 2014 - 10:44 AM

The print() is just if this code is not being run from a Python command (IDLE).

The original code won't run because the global x (in y()) hasn't been defined. Maybe I'm missing something?

### #8 jon.kiparsky

• Beginner

Reputation: 11072
• Posts: 18,910
• Joined: 19-March 11

## Re: A little help with List Comprehension

Posted 12 November 2014 - 01:39 PM

andrewsw, on 12 November 2014 - 12:44 PM, said:

The original code won't run because the global x (in y()) hasn't been defined. Maybe I'm missing something?

Well, I did copy it out of the python interpreter, just as you see it.

What you're missing is how python handles local scopes. You can reference a variable from outside the scope, but you can only write to a local, or to a global that's explicitly brought in with a global declaration. So the function y can see some x that's in its scope and report its value - but if I tried to write to it, I'd have trouble:

```>>> def z():
...   x = x+3
>>> for x in range (10):
...     z()
...     print x
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "<stdin>", line 2, in z
UnboundLocalError: local variable 'x' referenced before assignment
>>>
```

Basically, we're looking at the same scenario as this one:

```>>> def y():
...   return x*x
...
>>> del(x)
>>> y()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in y
NameError: global name 'x' is not defined
>>> x = 4
>>> y()
16
>>>
```

In the first case, x is not declared, so it's an error. But when I set a value for x, python is happy to read it. However, I still can't write to it:
```>>> z()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in z
UnboundLocalError: local variable 'x' referenced before assignment

```

...because python assumes that all writes are to locals. But of course, this works fine:

```>>> def z2():
...   global x
...   x+=2
>>> x
4
>>> z2()
>>> x
6
```

Now, I should point out that my original y is a terrible function, and if I came across it in the real world, I'd take it out back and shoot it in the head. But as an example of how list comps work, it's okay.

### #9 andrewsw

• RequestedRangeNotSatisfiable

Reputation: 6552
• Posts: 26,566
• Joined: 12-December 12

## Re: A little help with List Comprehension

Posted 13 November 2014 - 11:40 AM

I am still unable to run your example in either IDLE or the Python Interactive Shell:

I just don't see how x is leaking out of the comprehension..

Anyway, I ain't going to lose sleep over it, but it remains a mystery (to me) how you were able to run this.

### #10 jon.kiparsky

• Beginner

Reputation: 11072
• Posts: 18,910
• Joined: 19-March 11

## Re: A little help with List Comprehension

Posted 13 November 2014 - 11:53 AM

Hm. Looks like scope rules changed in python 3. So my example only goes for the python that people are actually using. />

Python:

```Python 2.7.5 (default, Mar  9 2014, 22:15:05)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin
>>> def y():
...     return x*x
...
>>> [y() for x in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>>
```

Python 3:

```Python 3.3.4 (default, Mar 13 2014, 11:09:17)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.2.79)] on darwin
>>> def y():
...     return x*x
...
>>> x = 4
>>> y()
16
>>> [y() for x in range (10)]
[16, 16, 16, 16, 16, 16, 16, 16, 16, 16]
>>>
```

### #11 andrewsw

• RequestedRangeNotSatisfiable

Reputation: 6552
• Posts: 26,566
• Joined: 12-December 12

## Re: A little help with List Comprehension

Posted 13 November 2014 - 11:57 AM

Mystery solved

### #12 CyberPat

Reputation: 1
• Posts: 28
• Joined: 25-September 14

## Re: A little help with List Comprehension

Posted 14 November 2014 - 11:55 AM

andrewsw, on 12 November 2014 - 04:12 AM, said:

The first statement won't work. Try:
```print([y for x in range(51)])
```

Quote

NameError: global name 'y' is not defined

```print([x for x in range(51)])
```

will work, as will
```print([x*2 for x in range(51)])
```

so the first part - the output - is an expression based on the generated output of the list on the right.

http://www.pythonfor...sions-in-python

Thank you so much for the great answer. Why is x considered an expression here? And why can't we set y as our out function?

### #13 andrewsw

• RequestedRangeNotSatisfiable

Reputation: 6552
• Posts: 26,566
• Joined: 12-December 12

## Re: A little help with List Comprehension

Posted 14 November 2014 - 12:01 PM

x is considered an expression because it results in a value - the output - just as x * 2 does.
```[Y for x in LIST]
```

You can't use Y here because it hasn't been defined anywhere. Jon's examples demonstrate that you could use y() if you have already defined some function y() that returns a value.

### #14 CyberPat

Reputation: 1
• Posts: 28
• Joined: 25-September 14

## Re: A little help with List Comprehension

Posted 14 November 2014 - 04:40 PM

Thanks! In fact,in the following list comprehension, the first x is kinda same as the loop variable and that's why we don't get a global name error while using it, am i right?

s = [x for x in range(51)

### #15 jon.kiparsky

• Beginner

Reputation: 11072
• Posts: 18,910
• Joined: 19-March 11

## Re: A little help with List Comprehension

Posted 14 November 2014 - 04:56 PM

yep. In fact, it is the same as the loop variable - basically, it can be an arbitrary python expression, and a variable counts as an expression (evaluating to the right-hand value of the variable)

Think about that post where I unrolled the listcomp for you: this is identical to

```s = []
for x in range (51):
s.append(x)

```

so you can see this as:

```somelist = [ EXP for ITERATOR in ITERABLE ]
```

which is equivalent to

```somelist = []
for ITERATOR in ITERABLE:
somelist.append(EXP)
```

In both cases, the Expression's scope includes the ITERATOR. That's probably the weird part: you're used to having the iterator declared before we it's used. In the list comp, it comes after, but since the whole thing is parsed by the interpreter as one chunk, that's not a problem.