Many newbie questions regarding python
steve at REMOVE-THIS-cybersource.com.au
Fri Oct 8 02:27:21 CEST 2010
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 =  * 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
v = *20 # now initialise v before using it
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:
v = *20 # create v before using it
> 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):
Two more alternatives:
v = list(range(20)) # in Python 2.x you can leave out the call to list()
v = 
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:
self.f = 1
> 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
Remember that Python uses nested namespaces. Inside the method C.g above
the namespaces that are searched are:
any non-local (nested) functions or closures (none in this example)
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:
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,
More information about the Python-list