Questions about list-creation

Discussion in 'Python' started by Manuel Graune, Nov 30, 2009.

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

    --
    A hundred men did the rational thing. The sum of those rational choices was
    called panic. Neal Stephenson -- System of the world
    http://www.graune.org/GnuPG_pubkey.asc
    Key fingerprint = 1E44 9CBD DEE4 9E07 5E0A 5828 5476 7E92 2DB4 3C99
     
    Manuel Graune, Nov 30, 2009
    #1
    1. Advertising

  2. Manuel Graune

    inhahe Guest

    On Mon, Nov 30, 2009 at 12:22 PM, Manuel Graune <> wrote:
    >
    > 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

    >
    > Regards,
    >
    > Manuel Graune
    >
    > --
    > A hundred men did the rational thing. The sum of those rational choices was
    > called panic. Neal Stephenson -- System of the world
    > http://www.graune.org/GnuPG_pubkey.asc
    > Key fingerprint = 1E44 9CBD DEE4 9E07 5E0A  5828 5476 7E92 2DB4 3C99
    > --
    > http://mail.python.org/mailman/listinfo/python-list
    >
     
    inhahe, Nov 30, 2009
    #2
    1. Advertising

  3. Manuel Graune

    Lie Ryan Guest

    On 12/1/2009 4:22 AM, Manuel Graune wrote:
    >
    > 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):
    File "<stdin>", line 1, in <module>
    NameError: name 'i' is not defined
    >>> a = list(i for i in range(10))
    >>> i

    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    NameError: name 'i' is not defined
    >>> ^Z
     
    Lie Ryan, Nov 30, 2009
    #3
  4. Manuel Graune

    Mel Guest

    Manuel Graune wrote:

    > 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.
     
    Mel, Nov 30, 2009
    #4
  5. Manuel Graune

    inhahe Guest

    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.




    On Mon, Nov 30, 2009 at 1:12 PM, inhahe <> wrote:
    > On Mon, Nov 30, 2009 at 12:22 PM, Manuel Graune <> wrote:
    >>
    >> 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
    >
    >>
    >> Regards,
    >>
    >> Manuel Graune
    >>
    >> --
    >> A hundred men did the rational thing. The sum of those rational choices was
    >> called panic. Neal Stephenson -- System of the world
    >> http://www.graune.org/GnuPG_pubkey.asc
    >> Key fingerprint = 1E44 9CBD DEE4 9E07 5E0A  5828 5476 7E92 2DB4 3C99
    >> --
    >> http://mail.python.org/mailman/listinfo/python-list
    >>

    >
     
    inhahe, Nov 30, 2009
    #5
  6. On Monday 30 November 2009 12:22:17 pm Manuel Graune wrote:
    >
    > 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.

    --
    Luis Zarrabeitia (aka Kyrie)
    Fac. de Matemática y Computación, UH.
    http://profesores.matcom.uh.cu/~kyrie
     
    Luis Zarrabeitia, Nov 30, 2009
    #6
  7. Manuel Graune

    Terry Reedy Guest

    Manuel Graune wrote:
    > 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(1)

    Help on int object:
    ....

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

    Try

    >>> help()

    ....
    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
     
    Terry Reedy, Nov 30, 2009
    #7
  8. Thanks to all of you. You have been most helpful.

    Regards,

    Manuel Graune

    --
    A hundred men did the rational thing. The sum of those rational choices was
    called panic. Neal Stephenson -- System of the world
    http://www.graune.org/GnuPG_pubkey.asc
    Key fingerprint = 1E44 9CBD DEE4 9E07 5E0A 5828 5476 7E92 2DB4 3C99
     
    Manuel Graune, Dec 1, 2009
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. roopa
    Replies:
    6
    Views:
    792
    Jerry Coffin
    Aug 27, 2004
  2. sks
    Replies:
    4
    Views:
    416
    Alf P. Steinbach
    Jul 6, 2006
  3. Replies:
    3
    Views:
    410
    Daniel T.
    Oct 12, 2006
  4. Allard Warrink

    memory problem with list creation

    Allard Warrink, Jan 13, 2010, in forum: Python
    Replies:
    5
    Views:
    381
    Steven D'Aprano
    Jan 14, 2010
  5. Rajarshi Chakravarty

    file list sorted by creation date

    Rajarshi Chakravarty, Jan 8, 2011, in forum: Ruby
    Replies:
    5
    Views:
    146
    Michael Fellinger
    Jan 8, 2011
Loading...

Share This Page