Questions about list-creation

M

Manuel Graune

Hello,

in (most) python documentation the syntax "list()"
and "[]" is treated as being more or less the same
thing. For example "help([])" and "help(list())" point
to the same documentation. Since there are at least
two cases where this similarity is not the case, (see below)
can someone explain the reasoning behind this and point to
further / relevant documentation?
(To clarify: I am not complaining about this, just asking.)


1.)

when using local variables in list comprehensions, say

a=[i for i in xrange(10)]

the local variable is not destroyed afterwards:

print "a",a
print "i",i

using the similar code

b=list(j for j in xrange(10))

the local variable is destroyed after use:

print "b",b
print "j",j

and 2)

a=list([])

vs.

b=[[]]


Regards,

Manuel Graune
 
I

inhahe

Hello,

in (most) python documentation the syntax "list()"
and "[]" is treated as being more or less the same
thing. For example "help([])" and "help(list())" point
to the same documentation. Since there are at least
two cases where this similarity is not the case, (see below)
can someone explain the reasoning behind this and point to
further / relevant documentation?
(To clarify: I am not complaining about this, just asking.)


1.)

when using local variables in list comprehensions, say

a=[i for i in xrange(10)]

the local variable is not destroyed afterwards:

print "a",a
print "i",i

using the similar code

b=list(j for j in xrange(10))

the local variable is destroyed after use:

print "b",b
print "j",j

I could be wrong, but I think this was actually a bug that was fixed later.
and 2)

a=list([])

vs.

b=[[]]

those don't return the same thing
list([]) will create a shallow copy of [], which will of course be []

i can't think of a place where you'd want to use list() instead of [],
but sometimes you might want to use 'list', such as in a defaultdict,
in which case it's being used as a factory
 
L

Lie Ryan

Hello,

in (most) python documentation the syntax "list()"
and "[]" is treated as being more or less the same
thing. For example "help([])" and "help(list())" point
to the same documentation. Since there are at least
two cases where this similarity is not the case, (see below)
can someone explain the reasoning behind this and point to
further / relevant documentation?
(To clarify: I am not complaining about this, just asking.)


1.)

when using local variables in list comprehensions, say

a=[i for i in xrange(10)]

the local variable is not destroyed afterwards:

print "a",a
print "i",i

using the similar code

b=list(j for j in xrange(10))

the local variable is destroyed after use:

print "b",b
print "j",j


It's not so much about list() vs. [] but generator comprehension vs.
list comprehension. list() takes a generator comprehension, while
[listcomp] is its own syntax. List comprehension leaked its "loop
counter" to the surrounding namespace, while generator comprehension got
its own tiny namespace.

This "bug" (or feature, depending on your political alignment) is fixed
in Python 3.x:

Python 3.1.1 (r311:74483, Aug 17 2009, 17:02:12) [MSC v.1500 32 bit
(Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> a = [i for i in range(10)]
>>> i
Traceback (most recent call last):
Traceback (most recent call last):
 
M

Mel

Manuel said:
in (most) python documentation the syntax "list()"
and "[]" is treated as being more or less the same
thing. For example "help([])" and "help(list())" point
to the same documentation. Since there are at least
two cases where this similarity is not the case, (see below)
can someone explain the reasoning behind this and point to
further / relevant documentation?
(To clarify: I am not complaining about this, just asking.)


1.)

when using local variables in list comprehensions, say

a=[i for i in xrange(10)]

the local variable is not destroyed afterwards:

print "a",a
print "i",i

Long ago, lists were built using explicit code:

a = []
for i in xrange(10):
a.append (i)

which of course left i bound to the last value that was appended.

People decided later that this was wordier than it had to be, and could bury
the real point of a computation under a lot of boilerplate code that
initialized lists, so we got list comprehensions, as you note, and they
behave the same as the original code.
using the similar code

b=list(j for j in xrange(10))

the local variable is destroyed after use:

The list constructor is a lot more recent. It takes any iterable as an
argument and makes (or tries to make) a list with the resulting values. The
example you give takes a sequence comprehension as its argument. A sequence
comprehension doesn't create data values -- it creates a block of code that
can be executed later to create data values, and it can be executed later in
any context. So we could also code (untested):

def S():
return (j for j in xrange (10))

def T(s):
return list (s)

c = S()
b = T(c)

which still creates a list, but at an astonishing remove. The sequence
comprehension `c` can't count on finding a `j` in the namespace it finally
gets executed in, so it has to have it's own private namespace to use then.

That's why you don't see `j` in your local namespace when `list` finallty
runs the sequence comprehension.

Mel.
 
I

inhahe

i should also mention that

a=[i for i in xrange(10)]

and

b=list(j for j in xrange(10))

isn't really just a difference of using [] vs. list()
the first case is a list comprehension, the second case is a generator
comprehension which is then converted to a list
(the bug only applies to list comprehensions, not generator comprehensions)

i.e. notice that you can do this
''.join(x for x in ['a','b','c'])
no list or [] involved - it's just a generator comprehension being
passed to a function.




Hello,

in (most) python documentation the syntax "list()"
and "[]" is treated as being more or less the same
thing. For example "help([])" and "help(list())" point
to the same documentation. Since there are at least
two cases where this similarity is not the case, (see below)
can someone explain the reasoning behind this and point to
further / relevant documentation?
(To clarify: I am not complaining about this, just asking.)


1.)

when using local variables in list comprehensions, say

a=[i for i in xrange(10)]

the local variable is not destroyed afterwards:

print "a",a
print "i",i

using the similar code

b=list(j for j in xrange(10))

the local variable is destroyed after use:

print "b",b
print "j",j

I could be wrong, but I think this was actually a bug that was fixed later.
and 2)

a=list([])

vs.

b=[[]]

those don't return the same thing
list([]) will create a shallow copy of [], which will of course be []

i can't think of a place where you'd want to use list() instead of [],
but sometimes you might want to use 'list', such as in a defaultdict,
in which case it's being used as a factory
 
L

Luis Zarrabeitia

when using local variables in list comprehensions, say

a=[i for i in xrange(10)]

the local variable is not destroyed afterwards: [...]
b=list(j for j in xrange(10))

the local variable is destroyed after use:

Actually, [] and list() are not the same. For instance, list(1,2) rises an
error, while [1,2] is the list with two elements.

The comprehension is just a syntactic contruct that allows you to simplify the
creation of lists, while the list() "function" (it is a class, actually)
receives an iterable object and returns a list.

What you seem to be confused about is the construct:

(j for j in xrange(10))

That is called a generator expression, and it is very similar to the list
comprehension, except that it builds an iterator (instead of a list, i.e, the
xrange(10) is not consumed until it is needed), and the loop variable
doesn't "leak" outside.

When you do b=list(j for j in xrange(10)), you are actually doing

b=list((j for j in xrange(10)))

(note the extra set of parenthesis - python lets you ommit those), i.e, you
are calling the list() "function" with a single argument, an iterable that
contains all the elements of xrange(10). You could be calling

foobar(j for j in xrange(10))

instead.

And I think I lost my way... I'm sleepy. If I confused you, sorry... and if
I'm helped you, thank you for letting me :D.

Cya.
 
T

Terry Reedy

Manuel said:
in (most) python documentation the syntax "list()"
and "[]" is treated as being more or less the same
thing.

Untrue. List() and [] happen to both evaluate to the same thing, an
empty list. But there is no reason to expect list(<sometext>) and
[<sometext>] to always evaluate to the same thing. The docs for list()
calls and [] displays and comprehensions are quite different.

In particular, they clearly say that [x] interprets x as an item and
creates a list with one item, x, while list(x) interprets x as an
iterable, and creates a list with multiple items, the items of x. So. in
particular, list([]) != [[]].
For example "help([])" and "help(list())" point
to the same documentation.

This has nothing to do with list(text) and [text]. [] evaluates to an
instance that has no doc string, so help backs up to its class. Compare
Help on int object:
....

The alternative to to print nothing, which would not be very helpful.

Try
....
help> topics

and you will see that there is a topic LISTLITERALS, though not one for
comprehensions or sets or even generators. The list of topics seems not
to have been kept up to date.

Terry Jan Reedy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top