Many newbie questions regarding python

Discussion in 'Python' started by Rogério Brito, Oct 8, 2010.

  1. Hi there.

    I am used to some languages like C, but I am just a complete newbie with Python
    and, while writing some small snippets, I had encountered some problems, with
    which I would sincerely appreciate any help, since I appreciate this language to
    write my "running pseudocode in" and I am seriously thinking of using it to
    teach some algorithms classes.

    1 - The first issue that I am having is that I don't seem to be able to, say,
    use something that would be common for people writing programs in C: defining a
    one-dimensional vector and only initializing it when needed.

    For instance, in C, I would write something like:

    int v[20];
    for (i = 0; i < 20; i++)
    v = 0;

    Note that I only define the vector v (and its size) at the beginning but
    initialize it latter during the code per-se.

    My first try to write it in Python was something like this:

    v = []
    for i in range(20):
    v = 0

    Unfortunately, this doesn't work, as I get an index out of bounds when trying to
    index the v list. Of course, the main difference between the two snippets is
    that, in C, I declared v to have 20 positions, while in python I initialized it
    to be the empty list and, indeed, it has an empty set of indexes.

    What is the Pythonic way of writing code like this? So far, I have found many
    alternatives and I would like to write code that others in the Python community
    would find natural to read. Some of the things that crossed my mind:

    v = [0 for i in range(20)]

    v = [0] * 20

    v = []
    for i in range(20): v.append(0)

    What should I prefer? Any other alternative?

    If possible, I would like to simply declare the list and fill it latter in my
    program, as lazily as possible (this happens notoriously when one is using a
    technique of programming called dynamic programming where initializing all
    positions of a table may take too much time in comparison to the filling of the
    array).


    2 - If I declare a class with some member variables, is is strictly necessary
    for me to qualify those members in a method in that class? For instance, if I
    define:

    class C:
    f = 1
    def g(self):
    return f

    I get an annoying message when I try to call the g method in an object of type
    C, telling me that there's no global symbol called f. If I make g return self.f
    instead, things work as expected, but the code loses some readability.

    Is there any way around this or is that simply "a matter of life"?

    I have some other questions, but I will save them for latter.

    Please, keep in mind that I am a newbie in Python. Despite that, I am enjoying
    the little that I know.


    Thank you very much in advance,

    --
    Rogério Brito : rbrito@{ime.usp.br,gmail.com} : GPG key 4096R/BCFCAAAA
    http://rb.doesntexist.org : Packages for LaTeX : algorithms.berlios.de
    DebianQA: http://qa.debian.org/developer.php?login=
    Rogério Brito, Oct 8, 2010
    #1
    1. Advertising

  2. Rogério Brito

    Carl Banks Guest

    On Oct 7, 4:10 pm, Rogério Brito <> wrote:
    [snip]
    >
    >     v = [0 for i in range(20)]
    >
    >     v = [0] * 20
    >
    >     v = []
    >     for i in range(20): v.append(0)
    >
    > What should I prefer? Any other alternative?


    The Pythonic way is to not to preinitialize the list at all. Don't
    put anything in the list until you have the data you need.

    > If possible, I would like to simply declare the list and fill it latter in my
    > program, as lazily as possible (this happens notoriously when one is using a
    > technique of programming called dynamic programming where initializing all
    > positions of a table may take too much time in comparison to the filling of the
    > array).


    So, if I understand you, you are thinking of your list as a table with
    dynamically calculated entries, and want to calculate the entries upon
    request.

    Three possibilities:

    1. Initialize the list using v = [None]*n (I recomment using None
    instead of 0 for this, in most cases)

    2. Use a dict instead. Dict items pop into existence if you assign
    with a key that doesn't exist.

    v = {}

    Then you can do

    v[1] = a
    v[10] = n
    v[999] = c

    3. Consider numpy, which allows preallocation of lists:

    v = np.zeros(100)


    [snip]
    > For instance, if I
    > define:
    >
    > class C:
    >     f = 1
    >     def g(self):
    >         return f
    >
    > I get an annoying message when I try to call the g method in an object of type
    > C, telling me that there's no global symbol called f. If I make g return self.f
    > instead, things work as expected, but the code loses some readability.
    >
    > Is there any way around this or is that simply "a matter of life"?


    Matter of life. It's that way by design.


    Carl Banks
    Carl Banks, Oct 8, 2010
    #2
    1. Advertising

  3. On Thu, 07 Oct 2010 20:10:14 -0300 Rogério Brito <>
    wrote:

    > I am used to some languages like C, but I am just a complete newbie
    > with Python and, while writing some small snippets, I had encountered
    > some problems, with which I would sincerely appreciate any help,
    > since I appreciate this language to write my "running pseudocode in"
    > and I am seriously thinking of using it to teach some algorithms
    > classes.
    >

    Let me congratulate you on your choice.


    > 1 - The first issue that I am having is that I don't seem to be able
    > to, say, use something that would be common for people writing
    > programs in C: defining a one-dimensional vector and only
    > initializing it when needed.
    > [snip]

    I could be cheeky here and ask "Do you really need this? REALLY?". And
    I will: Really? ;)

    >
    > Note that I only define the vector v (and its size) at the beginning
    > but initialize it latter during the code per-se.
    >
    > [snip]
    >
    > What is the Pythonic way of writing code like this? So far, I have
    > found many alternatives and I would like to write code that others in
    > the Python community would find natural to read. Some of the things
    > that crossed my mind:
    >
    > v = [0 for i in range(20)]
    >

    Pretty good.


    > v = [0] * 20
    >

    This will break on you if you replace the zeros with mutable objects.
    Try it, you'll be unpleasantly surprised.

    I guess it's OK for numbers, though. Or tuples, if need be.


    > v = []
    > for i in range(20): v.append(0)
    >

    That's the older (pre list comp) way, I guess. No need for it anymore,
    unless the initialization is more complicated than this.


    >
    > If possible, I would like to simply declare the list and fill it
    > latter in my program, as lazily as possible (this happens notoriously
    > when one is using a technique of programming called dynamic
    > programming where initializing all positions of a table may take too
    > much time in comparison to the filling of the array).
    >

    Nah, don't worry too much about performance. You can do that when your
    program is too slow.

    I know that this isn't too satisfying, but seriously: Try to write
    programs for humans, not for the computer. (I'm talking about Python
    here; in C it's certainly par for the course to try to think like a
    computer does.)


    > 2 - If I declare a class with some member variables, is is strictly
    > necessary for me to qualify those members in a method in that class?
    > For instance, if I define:
    >
    > class C:
    > f = 1
    > def g(self):
    > return f
    >
    > I get an annoying message when I try to call the g method in an
    > object of type C, telling me that there's no global symbol called f.
    > If I make g return self.f instead, things work as expected, but the
    > code loses some readability.
    >

    No it doesn't.

    (... pedagogical pause ...)

    Python kind of forces you to be *very* explicit about which f you mean.
    And this is a good thing. If you mean the global f, then say f. If you
    mean the instance attribute of the current instance then say self.f and
    if you mean the class attribute then say C.f (or, if you fear you're
    going to be renaming C a lot, self.__class__.f).

    Note here that self.f refers to the f as accessible by the
    specific *instance* of the class, *not* the class attribute C.f. If you
    don't change f on the instance, then they'll coincide, otherwise they
    won't. Example (warning: not Python 3 compatible!):

    [wildemar@localhost ~]$ ipython
    Python 2.5.2 (r252:60911, Sep 30 2008, 15:41:38)
    Type "copyright", "credits" or "license" for more information.

    IPython 0.8.4 -- An enhanced Interactive Python.
    ? -> Introduction and overview of IPython's features.
    %quickref -> Quick reference.
    help -> Python's own help system.
    object? -> Details about 'object'. ?object also works, ?? prints more.

    In [1]: class C:
    ...: f = 1
    ...: def g(self):
    ...: return self.f
    ...:
    ...:

    In [2]: c = C();

    In [3]: print c.g()
    1

    In [4]: C.f = 2

    In [5]: print c.g()
    2

    In [6]: c.f = 3

    In [7]: print c.g()
    3

    In [8]: print C.f
    2



    > Is there any way around this or is that simply "a matter of life"?
    >

    Yes.


    > I have some other questions, but I will save them for latter.
    >

    Keep 'em coming. But be prepared for hearing "get used to it" many a
    time. Or, from the more harsh folks, "don't try to write C in
    Python". :)


    > Please, keep in mind that I am a newbie in Python. Despite that, I am
    > enjoying the little that I know.
    >

    Really? I never enjoy knowing just a little. ;)



    --
    To reach me via email, replace INVALID with the country code of my home
    country. But if you spam me, I'll be one sour kraut.
    Andreas Waldenburger, Oct 8, 2010
    #3
  4. Rogério Brito

    Guest

    On Oct 7, 6:10 pm, Rogério Brito <> wrote:
    > Hi there.
    >
    > I am used to some languages like C, but I am just a complete newbie with Python
    > and, while writing some small snippets, I had encountered some problems, with
    > which I would sincerely appreciate any help, since I appreciate this language to
    > write my "running pseudocode in" and I am seriously thinking of using it to
    > teach some algorithms classes.
    >
    > 1 - The first issue that I am having is that I don't seem to be able to, say,
    > use something that would be common for people writing programs in C: defining a
    > one-dimensional vector and only initializing it when needed.
    >
    > For instance, in C, I would write something like:
    >
    > int v[20];
    > for (i = 0; i < 20; i++)
    >     v = 0;
    >
    > Note that I only define the vector v (and its size) at the beginning but
    > initialize it latter during the code per-se.
    >
    > My first try to write it in Python was something like this:
    >
    > v = []
    > for i in range(20):
    >     v = 0
    >
    > Unfortunately, this doesn't work, as I get an index out of bounds when trying to
    > index the v list. Of course, the main difference between the two snippets is
    > that, in C, I declared v to have 20 positions, while in python I initialized it
    > to be the empty list and, indeed, it has an empty set of indexes.
    >
    > What is the Pythonic way of writing code like this? So far, I have found many
    > alternatives and I would like to write code that others in the Python community
    > would find natural to read. Some of the things that crossed my mind:
    >
    >     v = [0 for i in range(20)]
    >
    >     v = [0] * 20
    >
    >     v = []
    >     for i in range(20): v.append(0)
    >
    > What should I prefer? Any other alternative?
    >
    > If possible, I would like to simply declare the list and fill it latter in my
    > program, as lazily as possible (this happens notoriously when one is using a
    > technique of programming called dynamic programming where initializing all
    > positions of a table may take too much time in comparison to the filling of the
    > array).
    >
    > 2 - If I declare a class with some member variables, is is strictly necessary
    > for me to qualify those members in a method in that class? For instance, if I
    > define:
    >
    > class C:
    >     f = 1
    >     def g(self):
    >         return f
    >
    > I get an annoying message when I try to call the g method in an object of type
    > C, telling me that there's no global symbol called f. If I make g return self.f
    > instead, things work as expected, but the code loses some readability.
    >
    > Is there any way around this or is that simply "a matter of life"?
    >
    > I have some other questions, but I will save them for latter.
    >
    > Please, keep in mind that I am a newbie in Python. Despite that, I am enjoying
    > the little that I know.
    >
    > Thank you very much in advance,
    >
    > --
    > Rogério Brito : rbrito@{ime.usp.br,gmail.com} : GPG key 4096R/BCFCAAAAhttp://rb.doesntexist.org: Packages for LaTeX : algorithms.berlios.de
    > DebianQA:http://qa.debian.org/developer.php?login=


    How about:

    v = [None] * 20

    That way, you're not initializing with an artifical value like 0.
    , Oct 8, 2010
    #4
  5. Rogério Brito

    MRAB Guest

    On 08/10/2010 00:10, Rogério Brito wrote:
    > Hi there.
    >
    > I am used to some languages like C, but I am just a complete newbie with Python
    > and, while writing some small snippets, I had encountered some problems, with
    > which I would sincerely appreciate any help, since I appreciate this language to
    > write my "running pseudocode in" and I am seriously thinking of using it to
    > teach some algorithms classes.
    >
    > 1 - The first issue that I am having is that I don't seem to be able to, say,
    > use something that would be common for people writing programs in C: defining a
    > one-dimensional vector and only initializing it when needed.
    >
    > For instance, in C, I would write something like:
    >
    > int v[20];
    > for (i = 0; i< 20; i++)
    > v = 0;
    >
    > Note that I only define the vector v (and its size) at the beginning but
    > initialize it latter during the code per-se.
    >
    > My first try to write it in Python was something like this:
    >
    > v = []
    > for i in range(20):
    > v = 0
    >
    > Unfortunately, this doesn't work, as I get an index out of bounds when trying to
    > index the v list. Of course, the main difference between the two snippets is
    > that, in C, I declared v to have 20 positions, while in python I initialized it
    > to be the empty list and, indeed, it has an empty set of indexes.
    >
    > What is the Pythonic way of writing code like this? So far, I have found many
    > alternatives and I would like to write code that others in the Python community
    > would find natural to read. Some of the things that crossed my mind:
    >
    > v = [0 for i in range(20)]
    >
    > v = [0] * 20
    >
    > v = []
    > for i in range(20): v.append(0)
    >
    > What should I prefer? Any other alternative?
    >
    > If possible, I would like to simply declare the list and fill it latter in my
    > program, as lazily as possible (this happens notoriously when one is using a
    > technique of programming called dynamic programming where initializing all
    > positions of a table may take too much time in comparison to the filling of the
    > array).
    >

    Python doesn't have declarations. The code:

    v = []

    simply creates an empty list and binds the name 'v' to it. If you want
    to create a list containing 20 zeros then:

    v = [0] * 20

    is the Pythonic way. Which one you do depends on the particular problem
    you're working on; do whichever makes the most sense.
    >
    > 2 - If I declare a class with some member variables, is is strictly necessary
    > for me to qualify those members in a method in that class? For instance, if I
    > define:
    >
    > class C:
    > f = 1
    > def g(self):
    > return f
    >
    > I get an annoying message when I try to call the g method in an object of type
    > C, telling me that there's no global symbol called f. If I make g return self.f
    > instead, things work as expected, but the code loses some readability.
    >
    > Is there any way around this or is that simply "a matter of life"?
    >

    The name 'f' in that case is an attribute of the class itself. If you
    want it to be an attribute of an instance of the class then do
    something like this:

    class C:
    def __init__(self):
    self.f = 1
    def g(self):
    return self.f

    You should write Python code in the Python idiom and not try to look
    for the Python equivalent of a C idiom. In other words, don't try to
    write a C program in Python! You might want to read "The Zen of
    Python". Just type:

    help("this")

    at the Python prompt.
    MRAB, Oct 8, 2010
    #5
  6. On Fri, 08 Oct 2010 00:46:41 +0100 MRAB <>
    wrote:

    > In other words, don't try to write a C program in Python!


    Man, I'm good. :D

    /W

    --
    To reach me via email, replace INVALID with the country code of my home
    country. But if you spam me, I'll be one sour kraut.
    Andreas Waldenburger, Oct 8, 2010
    #6
  7. Rogério Brito

    Tim Harig Guest

    On 2010-10-07, Rogério Brito <> wrote:
    > 1 - The first issue that I am having is that I don't seem to be able to, say,
    > use something that would be common for people writing programs in C: defining a
    > one-dimensional vector and only initializing it when needed.
    >
    > For instance, in C, I would write something like:
    >
    > int v[20];
    > for (i = 0; i < 20; i++)
    > v = 0;
    >
    > Note that I only define the vector v (and its size) at the beginning but
    > initialize it latter during the code per-se.


    You are reserving enough space to be defined as an array of 20 integers.
    Note that after you declare it, you *can* access those memory locations
    even before you initialize them. They therefore still contain something
    even if you have not yet defined what that something is. Note that
    uninitialized variables are a common C error.

    Python is dynamic. You never need to allocate memory for something, you
    simply assign something and the system takes care of the allocation for
    you. Before something is assigned, it cannot be addressed. Nothing takes
    up memory before it is assigned.

    > Unfortunately, this doesn't work, as I get an index out of bounds when trying to
    > index the v list. Of course, the main difference between the two snippets is
    > that, in C, I declared v to have 20 positions, while in python I initialized it
    > to be the empty list and, indeed, it has an empty set of indexes.
    >
    > What is the Pythonic way of writing code like this? So far, I have found many
    > alternatives and I would like to write code that others in the Python community
    > would find natural to read. Some of the things that crossed my mind:
    >
    > v = [0 for i in range(20)]
    >
    > v = [0] * 20
    >
    > v = []
    > for i in range(20): v.append(0)
    >
    > What should I prefer? Any other alternative?


    It really would help to know what you are trying to with v. If we knew
    that, we might be able to make better suggestions. Usually in Python,
    there is no need to initialize elements in a list as you can simply add
    them as you need them.

    > If possible, I would like to simply declare the list and fill it latter in my
    > program, as lazily as possible (this happens notoriously when one is using a
    > technique of programming called dynamic programming where initializing all
    > positions of a table may take too much time in comparison to the filling of the
    > array).


    What I *think* you *might* be looking for is a kind of sparse list. You
    can achieve this by using a dictionary with numeric keys rather then a
    list. Not that when you do this, you recreate the C problem of trying to
    access something that has not been allocated. You either need to make sure
    that a key exists before trying to access it or catch and handleKeyError.

    > 2 - If I declare a class with some member variables, is is strictly necessary
    > for me to qualify those members in a method in that class? For instance, if I
    > define:
    >
    > class C:
    > f = 1
    > def g(self):
    > return f


    Note that you have assigned f to the class object and not to the instance
    objects. This is a common pitfall for new Python programmers. I suggest
    assigning f in the constructor unless you are really sure that you want to
    assign it to the class object which will be shared among the instance
    objects.

    > I get an annoying message when I try to call the g method in an object of type
    > C, telling me that there's no global symbol called f. If I make g return self.f
    > instead, things work as expected, but the code loses some readability.
    >
    > Is there any way around this or is that simply "a matter of life"?


    Each member functions has its own scope. The object itself is not part of
    this scope. Therefore, you must use the self object reference to access
    other members of the object containing the function.

    I don't really see the readability problem; but, you could work around it
    by creating a reference to the member at the start of the function:

    def g(self):
    f = self.f

    For this to work, f must be mutable. If f is not mutable then you can wrap
    f inside of a class in such a way that it is mutable. Do this at your own
    risk. In doing this, you are starting to play with fire.
    Tim Harig, Oct 8, 2010
    #7
  8. On Thu, 07 Oct 2010 20:10:14 -0300, Rogério Brito wrote:


    > What is the Pythonic way of writing code like this? So far, I have
    > found many alternatives and I would like to write code that others in
    > the Python community would find natural to read. Some of the things
    > that crossed my mind:
    >
    > v = [0 for i in range(20)]


    Absolutely not. Such a code snippet is very common, in fact I've done it
    myself, but it is a "hammer solution" -- to a small boy with a hammer,
    everything looks like a nail that needs hammering. Writing such a list
    comprehension is a "list comp solution".


    > v = [0] * 20


    Yes, this is the solution. But given your earlier explanation that you
    want to lazily initialise v, I don't think it applies, because it
    initialises it all at once. (Of course, such initialisation is cheap, but
    it does happen all at once.)

    If you are writing this:

    v = [] # declare v as an empty list
    do_something()
    do_something_else()
    v = [0]*20 # now initialise v before using it
    do_something_with(v)


    then such declarations are not necessary and are discouraged in Python.
    Having an unused, empty variable v floating around doing nothing is
    pointless in Python. Just write:

    do_something()
    do_something_else()
    v = [0]*20 # create v before using it
    do_something_with(v)



    > v = []
    > for i in range(20): v.append(0)


    I would never write that literally. It's as bad as the list comp, only it
    takes up more space. It too also fails to be lazy initialisation.
    However, using append is the correct way when you have a situation where
    you need to dynamically grow the list, e.g.:


    v = []
    for i in range(20):
    v.append(0)
    do_something_with(v)



    Two more alternatives:

    v = list(range(20)) # in Python 2.x you can leave out the call to list()

    or

    v = []
    v.extend(range(20))

    both initialise v to [0, 1, 2, 3, ... , 19] instead of [0, 0, ..., 0].




    > 2 - If I declare a class with some member variables, is is strictly
    > necessary for me to qualify those members in a method in that class? For
    > instance, if I define:


    In Python, we generally refer to "attributes" rather than "members".


    > class C:
    > f = 1
    > def g(self):
    > return f


    By the way, you have created a class attribute f which is shared by all
    instances. You probably want:

    class C:
    def __init__(self):
    self.f = 1
    def g(self):
    return self.f



    > I get an annoying message when I try to call the g method in an object
    > of type C, telling me that there's no global symbol called f.


    No you don't. You get a message that there is no global NAME called f.

    You might think I'm being pedantic, but I'm not. If you're thinking in
    terms of C language, you probably think that there is a symbol table
    created by the compiler so that Python can look at a reference "f" and
    say "oh, that's a member variable" at compile time, and only the correct
    value needs to be looked up at runtime. But that's not Python's execution
    model. *Everything* in Python is looked up dynamically at runtime in
    namespaces. (The only exceptions are statements.) So when you write "f",
    Python *cannot* know at compile time whether it is a local variable, a
    non-local, a global, an attribute (member) or something else. It must
    look the name up in one or more namespaces at runtime.


    (Of course, you might already know this, in which case, yes, I'm just
    being pedantic *grins* )



    > If I make
    > g return self.f instead, things work as expected, but the code loses
    > some readability.


    On the contrary, it increases readability, because it explicitly tells
    the reader that you are accessing an attribute f rather than a local
    variable.

    Remember that Python uses nested namespaces. Inside the method C.g above
    the namespaces that are searched are:

    local variables
    any non-local (nested) functions or closures (none in this example)
    global variables
    built-ins

    in that order. Each namespace is independent, and Python will never try
    to guess that f is an attribute of the instance or class unless you
    explicitly tell it so. For example, an attribute instance.len will never
    block access to the built-in function len().

    (Actually, there is one exception... when a class statement is executed
    for the first time, creating the class, local variables of the class
    block are identified as attributes. This is a case of practicality beats
    purity, since otherwise Python would need extra syntax for creating
    methods and class attributes.)


    Attributes have their own search order:

    instance attributes
    class attributes
    attributes of any base classes

    When you refer to instance.attribute, the namespaces are searched in that
    order for the name "attribute". The locals and globals are not searched.



    Hope this helps,



    --
    Steven
    Steven D'Aprano, Oct 8, 2010
    #8
  9. Rogério Brito

    alex23 Guest

    On Oct 8, 10:27 am, Steven D'Aprano <st...@REMOVE-THIS-
    cybersource.com.au> wrote:
    > >     v = [0 for i in range(20)]

    >
    > Absolutely not. Such a code snippet is very common, in fact I've done it
    > myself, but it is a "hammer solution" -- to a small boy with a hammer,
    > everything looks like a nail that needs hammering. Writing such a list
    > comprehension is a "list comp solution".
    >
    > >     v = [0] * 20

    >
    > Yes, this is the solution.


    But the list comp version will work as expected for mutable types,
    whereas the 'solution' only works for immutable types.

    If anything, I feel like the list comp version is the correct solution
    because of its reliability, whereas the multiplication form feels like
    either a lucky naive approach or relies on the reader to know the type
    of the initialising value and its mutability.
    alex23, Oct 8, 2010
    #9
  10. Rogério Brito wrote:
    > class C:
    > f = 1
    > def g(self):
    > return f
    >
    > I get an annoying message when I try to call the g method in an object of type
    > C, telling me that there's no global symbol called f. If I make g return self.f
    > instead, things work as expected, but the code loses some readability.
    >
    > Is there any way around this or is that simply "a matter of life"?
    >

    class C:
    f =1

    creates the 'C.f ' name. When 'f' is used in g, you'll get then an error.

    class C:
    f = 1
    def g(self):
    return C.f


    is the obvious solution. However it can be slightly improved. f is a
    class attribute, meaning it's common to all instances of the C class.
    Thus g would be a class method, and is here declared liek a instance
    method (the instance being self).

    class C:
    f = 1
    @classmethod
    def g(cls):
    return cls.f

    c1 = C()
    c2 = C()

    print c1.f, c2.f # f is not an attribute of c1 nor c2, thus the lookup
    will try in the class and find C.f
    1 1

    c1.f = 10 # this create the c1 instance attribute f != class attribute f
    c2.f = 20 # this create the c2 instance attribute f != class attribute f

    print c1.f, c2.f, c1.g(), c2.g(), C.f
    10 20 1 1 1

    Cheers,

    JM
    Jean-Michel Pichavant, Oct 8, 2010
    #10
  11. Rogério Brito

    BartC Guest

    "Rogério Brito" <> wrote in message
    news:i8lk0n$g38$...

    > My first try to write it in Python was something like this:
    >
    > v = []
    > for i in range(20):
    > v = 0
    >
    > Unfortunately, this doesn't work, as I get an index out of bounds when
    > trying to
    > index the v list.


    Python can't grow a list by assigning to out-of-bound elements (although,
    being the language it is, there is probably a way of achieving that by
    redefining how [] works...)

    > What is the Pythonic way of writing code like this? So far, I have found
    > many


    > v = [0 for i in range(20)]
    >
    > v = [0] * 20
    >
    > v = []
    > for i in range(20): v.append(0)
    >
    > What should I prefer? Any other alternative?


    v=[0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0]

    will also work. But none of these appeal too much. I would probably do:

    def newlist(length,init=0):
    return [init]*length
    ....
    v=newlist(1000)

    (with the proviso that someone mentioned when the init value is complex: you
    might not get unique copies of each).

    > If possible, I would like to simply declare the list and fill it latter in
    > my
    > program, as lazily as possible (this happens notoriously when one is using
    > a
    > technique of programming called dynamic programming where initializing all
    > positions of a table may take too much time in comparison to the filling
    > of the
    > array).


    A sparse array? Even if an array could be constructed by assigning to
    arbitrary elements, the gaps created would still need filling in with None
    or Unassigned.

    > 2 - If I declare a class with some member variables, is is strictly
    > necessary


    This is where I bail out...

    --
    Bartc
    BartC, Oct 8, 2010
    #11
  12. Rogério Brito

    nn Guest

    On Oct 7, 7:10 pm, Rogério Brito <> wrote:
    > Hi there.
    >
    > I am used to some languages like C, but I am just a complete newbie with Python
    > and, while writing some small snippets, I had encountered some problems, with
    > which I would sincerely appreciate any help, since I appreciate this language to
    > write my "running pseudocode in" and I am seriously thinking of using it to
    > teach some algorithms classes.
    >
    > 1 - The first issue that I am having is that I don't seem to be able to, say,
    > use something that would be common for people writing programs in C: defining a
    > one-dimensional vector and only initializing it when needed.
    >
    > For instance, in C, I would write something like:
    >
    > int v[20];
    > for (i = 0; i < 20; i++)
    >     v = 0;
    >
    > Note that I only define the vector v (and its size) at the beginning but
    > initialize it latter during the code per-se.
    >
    > My first try to write it in Python was something like this:
    >
    > v = []
    > for i in range(20):
    >     v = 0
    >
    > Unfortunately, this doesn't work, as I get an index out of bounds when trying to
    > index the v list. Of course, the main difference between the two snippets is
    > that, in C, I declared v to have 20 positions, while in python I initialized it
    > to be the empty list and, indeed, it has an empty set of indexes.
    >
    > What is the Pythonic way of writing code like this? So far, I have found many
    > alternatives and I would like to write code that others in the Python community
    > would find natural to read. Some of the things that crossed my mind:
    >
    >     v = [0 for i in range(20)]
    >
    >     v = [0] * 20
    >
    >     v = []
    >     for i in range(20): v.append(0)
    >
    > What should I prefer? Any other alternative?
    >
    > If possible, I would like to simply declare the list and fill it latter in my
    > program, as lazily as possible (this happens notoriously when one is using a
    > technique of programming called dynamic programming where initializing all
    > positions of a table may take too much time in comparison to the filling of the
    > array).


    Just to emphasize what Andreas said:
    While
    v = [0] * 20
    is nice and good,

    don't do this
    v = [ [] ] * 20

    or this
    v = [ {} ] * 20

    until you have played around with it on the interactive prompt to
    understand how it works.

    The difference of behavior of mutable vs immutable objects is one of
    the main pitfalls for beginners in Python. Everything is very
    consistent once you understand the assignment semantics, but it really
    confuses people accustomed to other languages that work differently.
    nn, Oct 8, 2010
    #12
  13. Rogério Brito

    Tim Harig Guest

    On 2010-10-08, BartC <> wrote:
    > "Rogério Brito" <> wrote in message
    > news:i8lk0n$g38$...
    >> If possible, I would like to simply declare the list and fill it latter in
    >> my
    >> program, as lazily as possible (this happens notoriously when one is using
    >> a
    >> technique of programming called dynamic programming where initializing all
    >> positions of a table may take too much time in comparison to the filling
    >> of the
    >> array).

    >
    > A sparse array? Even if an array could be constructed by assigning to


    I agree, what the OP seems to want (whether he actually needs it or not) is
    a sparse array.

    > A sparse array? Even if an array could be constructed by assigning to
    > arbitrary elements, the gaps created would still need filling in with None
    > or Unassigned.


    That is only true when attempting to address elements based on their
    position rather then something like rank. You could create an object
    with some kind of index attribute that you could search for built in.
    When you needed to access the element, you simply walked the list until
    you find the matching identifier. The spaces no longer need filling since
    you are not matching based on absolute position in the list. This is of
    course inefficient for large lists, and while there are several methods
    of making this method more efficient (indexing, skip linking, b-tree,
    etc), you can get what you want very efficiently most of the time by
    simply using the built in dictionary with integer keys instead of a list.
    Tim Harig, Oct 8, 2010
    #13
  14. On 2010-10-07, Rog??rio Brito <> wrote:

    > If possible, I would like to simply declare the list and fill it
    > latter in my program, as lazily as possible (this happens notoriously
    > when one is using a technique of programming called dynamic
    > programming where initializing all positions of a table may take too
    > much time in comparison to the filling of the array).


    At first you say you want a list, later you say you want an array.
    They're two different things. Arrays are variable-length and can be
    heterogeneous. If what you really want is a fixed-length, homogeneous
    array, then use an array instead of a list:

    http://docs.python.org/library/array.html

    > If I declare a class with some member variables, is is strictly
    > necessary for me to qualify those members in a method in that class?


    Yes.

    > I get an annoying message when I try to call the g method in an
    > object of type C, telling me that there's no global symbol called f.
    > If I make g return self.f instead, things work as expected, but the
    > code loses some readability.


    That's a matter of opinion. Some of us _like_ self.f since it
    explicitly shows the reader that f isn't a global or local but a class
    or instance variable. Any time you make the reader/maintainer guess
    what something is, that's a bug waiting to happen.

    > Is there any way around this or is that simply "a matter of life"?


    Well, that's how Python works. I won't comment on "life".

    --
    Grant Edwards grant.b.edwards Yow! I feel like a wet
    at parking meter on Darvon!
    gmail.com
    Grant Edwards, Oct 8, 2010
    #14
  15. On 2010-10-08, Grant Edwards <> wrote:
    > On 2010-10-07, Rog??rio Brito <> wrote:
    >
    >> If possible, I would like to simply declare the list and fill it
    >> latter in my program, as lazily as possible (this happens notoriously
    >> when one is using a technique of programming called dynamic
    >> programming where initializing all positions of a table may take too
    >> much time in comparison to the filling of the array).

    >
    > At first you say you want a list, later you say you want an array.
    > They're two different things. Arrays are variable-length and can be
    > heterogeneous.


    I meant _Lists_ are fixed-length and homogeneous

    > If what you really want is a fixed-length, homogeneous array, then
    > use an array instead of a list:
    >
    > http://docs.python.org/library/array.html


    Actually, that's not the right link either. I was thinking more of
    NumPy arrays, where you can create an arbitrary sized homogeneous
    array of a desired type (either uninitialized or filled with zeros or
    ones):

    http://www.scipy.org/Tentative_NumPy_Tutorial#head-d3f8e5fe9b903f3c3b2a5c0dfceb60d71602cf93

    If you're crunching so many numbers that initializing a list is
    a problem, then you probably ought to be using NumPy.

    --
    Grant Edwards grant.b.edwards Yow! for ARTIFICIAL
    at FLAVORING!!
    gmail.com
    Grant Edwards, Oct 8, 2010
    #15
  16. On 2010-10-08, Grant Edwards <> wrote:
    > On 2010-10-08, Grant Edwards <> wrote:
    >> On 2010-10-07, Rog??rio Brito <> wrote:
    >>
    >>> If possible, I would like to simply declare the list and fill it
    >>> latter in my program, as lazily as possible (this happens notoriously
    >>> when one is using a technique of programming called dynamic
    >>> programming where initializing all positions of a table may take too
    >>> much time in comparison to the filling of the array).

    >>
    >> At first you say you want a list, later you say you want an array.
    >> They're two different things. Arrays are variable-length and can be
    >> heterogeneous.

    >
    > I meant _Lists_ are fixed-length and homogeneous


    Damn. I should give up and go golfing.

    _Lists_ are variable-length and can be heterogenous.

    _Arrays_ are homogenous and sort-of fixed length.

    > [...] I was thinking more of NumPy arrays, where you can create an
    > arbitrary sized homogeneous array of a desired type (either
    > uninitialized or filled with zeros or ones):
    >
    > http://www.scipy.org/Tentative_NumPy_Tutorial#head-d3f8e5fe9b903f3c3b2a5c0dfceb60d71602cf93
    >
    > If you're crunching so many numbers that initializing a list is
    > a problem, then you probably ought to be using NumPy.


    --
    Grant Edwards grant.b.edwards Yow! I'm shaving!!
    at I'M SHAVING!!
    gmail.com
    Grant Edwards, Oct 8, 2010
    #16
  17. On 10/8/2010 10:15 AM Grant Edwards said...

    > Damn. I should give up and go golfing.


    +1 QOTW

    Emile
    Emile van Sebille, Oct 8, 2010
    #17
  18. On Thu, 7 Oct 2010 18:34:58 -0700 (PDT) alex23 <>
    wrote:

    > On Oct 8, 10:27 am, Steven D'Aprano <st...@REMOVE-THIS-
    > cybersource.com.au> wrote:
    > > >     v = [0 for i in range(20)]

    > >
    > > Absolutely not. Such a code snippet is very common, in fact I've
    > > done it myself, but it is a "hammer solution" -- to a small boy
    > > with a hammer, everything looks like a nail that needs hammering.
    > > Writing such a list comprehension is a "list comp solution".
    > >
    > > >     v = [0] * 20

    > >
    > > Yes, this is the solution.

    >
    > But the list comp version will work as expected for mutable types,
    > whereas the 'solution' only works for immutable types.
    >
    > If anything, I feel like the list comp version is the correct solution
    > because of its reliability, whereas the multiplication form feels like
    > either a lucky naive approach or relies on the reader to know the type
    > of the initialising value and its mutability.


    The "correct" solution is the one that works the way you want it to
    work (that's my definition, anyway). There is nothing "lucky" about
    building a list via [value]*count. It repeats (but not so much
    duplicates!) "value" "count" times. It is well defined (and, I think,
    justified) behavior.

    It ceases to be as useful when mutable types are involved, but so what?
    Use something else, then.

    And I think it is not too much to ask of a reader of Python to know
    that integers are immutable. There are enough pitfalls that make this
    knowledge rather important to have. (I'm actually not convinced that
    this works as an argument, but there you go.)

    TL;DR: Don't say "correct", say "appropriate".

    /W

    --
    To reach me via email, replace INVALID with the country code of my home
    country. But if you spam me, I'll be one sour Kraut.
    Andreas Waldenburger, Oct 8, 2010
    #18
  19. On Thu, 07 Oct 2010 18:34:58 -0700, alex23 wrote:

    > On Oct 8, 10:27 am, Steven D'Aprano <st...@REMOVE-THIS-
    > cybersource.com.au> wrote:
    >> >     v = [0 for i in range(20)]

    >>
    >> Absolutely not. Such a code snippet is very common, in fact I've done
    >> it myself, but it is a "hammer solution" -- to a small boy with a
    >> hammer, everything looks like a nail that needs hammering. Writing such
    >> a list comprehension is a "list comp solution".
    >>
    >> >     v = [0] * 20

    >>
    >> Yes, this is the solution.

    >
    > But the list comp version will work as expected for mutable types,
    > whereas the 'solution' only works for immutable types.


    Yes, that is a good point. Repeating the same mutable object may give
    surprising results.


    > If anything, I feel like the list comp version is the correct solution
    > because of its reliability, whereas the multiplication form feels like
    > either a lucky naive approach or relies on the reader to know the type
    > of the initialising value and its mutability.


    And how often do you have an list that you are creating where you don't
    know what items you have to initialise the list with?

    There are three common use-cases for the idiom the OP was describing:
    initialising a list with zeroes (or sometimes some other numeric value),
    initialising it with None, or creating a list-of-lists (or more rarely, a
    list-of-dicts). The first one is *far* more common than the next two.

    You are right to point out that the third case is a Python gotcha: [[]]*n
    doesn't behave as expected by the naive or inexperienced Python
    programmer. I should have mentioned it, and pointed out that in that case
    you do want a list comp [[] for i in range(n)].

    But that doesn't mean that the list comp is the general purpose solution.
    Consider the obvious use of the idiom:

    def func(arg, count):
    # Initialise the list.
    L = [arg for i in range(count)]
    # Do something with it.
    process(L, some_function)

    def process(L, f):
    # Do something with each element.
    for item in enumerate(L):
    f(item)


    Looks good, right? But it isn't, because it will suffer the exact same
    surprising behaviour if f modifies the items in place. Using a list comp
    doesn't save you if you don't know what the object is.



    --
    Steven
    Steven D'Aprano, Oct 9, 2010
    #19
  20. alex23 <> writes:

    > If anything, I feel like the list comp version is the correct solution
    > because of its reliability, whereas the multiplication form feels like
    > either a lucky naive approach or relies on the reader to know the type
    > of the initialising value and its mutability.


    Other than list comp being slower, I'd like to point out that in some
    cases the multiplication is far from being naive. Consider this
    pattern:

    def in_groups_of(n, iterable):
    """Yield items of iterable packed in tuples of size n."""
    return itertools.izip(*[iter(iterable)] * n)

    >>> for a, b, c in in_groups_of(3, xrange(9)):

    .... print a, b, c
    ....
    0 1 2
    3 4 5
    6 7 8

    In the call to itertools.izip we are actually counting on list
    repetition to refer to the same object. Rewriting it as the list
    comprehension would break it:

    def in_groups_of(n, iterable):
    return itertools.izip(*[iter(iterable) for _ in xrange(n)])

    >>> for a, b, c in in_groups_of(3, xrange(9)):

    .... print a, b, c
    ....
    0 0 0
    1 1 1
    2 2 2
    3 3 3
    4 4 4
    5 5 5
    6 6 6
    7 7 7
    8 8 8
    Hrvoje Niksic, Oct 9, 2010
    #20
    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. Marco Ippolito
    Replies:
    0
    Views:
    2,561
    Marco Ippolito
    Oct 11, 2004
  2. =?Utf-8?B?U3R1?=

    session vars how many is to many ?

    =?Utf-8?B?U3R1?=, Mar 5, 2005, in forum: ASP .Net
    Replies:
    5
    Views:
    322
  3. dee
    Replies:
    2
    Views:
    389
  4. Default User
    Replies:
    0
    Views:
    313
    Default User
    Oct 20, 2005
  5. Ali Syed
    Replies:
    3
    Views:
    543
    Mark McIntyre
    Oct 13, 2004
Loading...

Share This Page