newbie questions

J

John Machin

Fredrik said:
John said:
Of course, in this simple case, I wouldn't be likely to write the clear
function since the inline code is simpler and has less overhead:

def main()
var1 = []
var1.append('a')
var1[:] = []

Even less overhead: del var1[:]

even less overhead:

var1 = []

Firstly, your replacement is not functionally equivalent. Secondly, it
appears *NOT* to have less overhead:
python -m timeit "a=range(100); del a[:]"
100000 loops, best of 3: 3.56 usec per loop
python -m timeit "a=range(100); a=[]"
100000 loops, best of 3: 3.95 usec per loop
python -m timeit "a=range(1000); del a[:]"
10000 loops, best of 3: 25.3 usec per loop
python -m timeit "a=range(1000); a=[]"
10000 loops, best of 3: 33.1 usec per loop
[Python 2.4; Windows 2000; Athlon 1.4Ghz chip]
(if you rely on having multiple references to the same list, instead of referring
to the list by name, you may want to reconsider the design)

Indeed. The OP's insistence on emptying the container instead of
trashing it along with its contents -- which is my interpretation of
"it doesn't emty my var (i don't want to destroy the var, just make it
like if it just have been created" -- was intriguing but not explained
....
 
F

Fredrik Lundh

John said:
Even less overhead: del var1[:]

even less overhead:

var1 = []

Firstly, your replacement is not functionally equivalent.

do you really have to tell me that? (as I said, if you rely on the difference,
your design is probably flawed)
Secondly, it appears *NOT* to have less overhead:

did you ask your fingers ;-)

my benchmark told me it was faster, but that doesn't make sense, and I cannot
repeat that test; I suspect I compared plain assignent to the assign-to-slice variant.
or maybe I used a pre-Raymond version of Python...

</F>
 
S

Steve Holden

houbahop said:
Thank you everyone, but I still not understand why such a comon feature like
passing parameters byref that is present in most serious programming
languages is not possible in a clean way,here in python.

I have the habit to never use globals as far as possible and this involve
that my main function is passing some parameters by reference to subs to
allow them to modify the vars.

I would be sad to break my structured programming scheme because a lack of
feature.

In others languages you can use things like pointers to strings or
Mysub(byref MyVar) ....

and it does the trick :)
The Python language allows complex objects to be returned, so there are
two techniques you should be aware of.

1. If an argument is mutable (such as a list or a dictionary) then its
contents can be modified using the reference passed in as an argument.

2. If an argument is immutable then it can be modified by returning the
new value as a tuple element, in this way:

a, b, c = someFunc(a, b, c)

regards
Steve
 
N

Nick Coghlan

houbahop <d.lapasset"@bag.python.org said:
Thank you everyone, but I still not understand why such a comon feature like
passing parameters byref that is present in most serious programming
languages is not possible in a clean way,here in python.

I have the habit to never use globals as far as possible and this involve
that my main function is passing some parameters by reference to subs to
allow them to modify the vars.

Python could be said to pass everything by reference. You are getting caught
more by the difference between mutable and immutable types, than by the
distinction between 'pass by reference' and 'pass by value' that other languages
have (Python actually uses a blend of the two ideas - you get references passed
in, but it you use assignment on your arguments, the caller is not affected).

Items which are immutable can't be modified *at all* (not just in subroutines).
The only thing you can do is take the name that references them and make them
point to something else. Items which are mutable can be both modified and made
to point to something else.

A list is mutable:

..>>>L = L1 = [1, 2, 3]
..>>>L is L1
True
..>>>L += [4]
..>>>L is L1 # Modification leaves us referencing the same thing
True
..>>> print L, L1
[1, 2, 3, 4] [1, 2, 3, 4]
..>>> L = []
..>>> L is L1 # Assignment gives a reference to a different thing
False
..>>> print L, L1
[] [1, 2, 3, 4]

A string is not:

..>>>S = S1 = "123"
..>>>S is S1
True
..>>>S += "4" # Even modification gives a reference to a different thing
..>>>S is S1
False
..>>>print S, S1
"1234", "123"
I would be sad to break my structured programming scheme because a lack of
feature.

As you work with Python, you'll find a lot of the heavy lifting is done with
mutable types (particularly list and dict). For these, modification within a
function is quite straightforward (just modify the argument directly - e.g. by
adding items to a list or dictionary).

Immutable types (e.g. strings, numbers, tuples) are generally returned directly
from functions, rather than returned as 'output parameters'. The ability to
return multiple values easily (via "return a, b, c" & "x, y, z = myfunc()"
generally eliminates the need for 'by reference' output parameters as used by C,
C++, Java and the like.

Regards,
Nick.

P.S. If you *really*, *really*, *really* want to fake output parameters, just
wrap them in a list:

def myfunc(outputparam):
# Do something
outputparam[0] = result

x = [] # Like declaring x as a pointer to something
myfunc(x) # The function fills the 'pointer'
x = x[0] # We dereference our 'pointer'

There's generally a better way, though (which way that is depends greatly on the
context).

Cheers,
Nick.
 
H

houbahop

thanks, very usefull answer.

Immutable types (e.g. strings, numbers, tuples) are generally returned
directly from functions, rather than returned as 'output parameters'. The
ability to return multiple values easily (via "return a, b, c" & "x, y, z
= myfunc()" generally eliminates the need for 'by reference' output
parameters as used by C, C++, Java and the like.
P.S. If you *really*, *really*, *really* want to fake output parameters,
just wrap them in a list:

return multiple values is ok, I usualy use a function only to return one
value, for exemple : value=IsSomething(), returning true, to include that in
an if statement : if (isSomething(blabla) ) ... but It's not a problem to
change that habit. and as I have read somewhere about python : "Explicit is
better than implicit"

Dominique.


Nick Coghlan said:
houbahop <d.lapasset"@bag.python.org said:
Thank you everyone, but I still not understand why such a comon feature
like passing parameters byref that is present in most serious programming
languages is not possible in a clean way,here in python.

I have the habit to never use globals as far as possible and this involve
that my main function is passing some parameters by reference to subs to
allow them to modify the vars.

Python could be said to pass everything by reference. You are getting
caught more by the difference between mutable and immutable types, than by
the distinction between 'pass by reference' and 'pass by value' that other
languages have (Python actually uses a blend of the two ideas - you get
references passed in, but it you use assignment on your arguments, the
caller is not affected).

Items which are immutable can't be modified *at all* (not just in
subroutines). The only thing you can do is take the name that references
them and make them point to something else. Items which are mutable can be
both modified and made to point to something else.

A list is mutable:

.>>>L = L1 = [1, 2, 3]
.>>>L is L1
True
.>>>L += [4]
.>>>L is L1 # Modification leaves us referencing the same thing
True
.>>> print L, L1
[1, 2, 3, 4] [1, 2, 3, 4]
.>>> L = []
.>>> L is L1 # Assignment gives a reference to a different thing
False
.>>> print L, L1
[] [1, 2, 3, 4]

A string is not:

.>>>S = S1 = "123"
.>>>S is S1
True
.>>>S += "4" # Even modification gives a reference to a different thing
.>>>S is S1
False
.>>>print S, S1
"1234", "123"
I would be sad to break my structured programming scheme because a lack
of feature.

As you work with Python, you'll find a lot of the heavy lifting is done
with mutable types (particularly list and dict). For these, modification
within a function is quite straightforward (just modify the argument
directly - e.g. by adding items to a list or dictionary).

Immutable types (e.g. strings, numbers, tuples) are generally returned
directly from functions, rather than returned as 'output parameters'. The
ability to return multiple values easily (via "return a, b, c" & "x, y, z
= myfunc()" generally eliminates the need for 'by reference' output
parameters as used by C, C++, Java and the like.

Regards,
Nick.

P.S. If you *really*, *really*, *really* want to fake output parameters,
just wrap them in a list:

def myfunc(outputparam):
# Do something
outputparam[0] = result

x = [] # Like declaring x as a pointer to something
myfunc(x) # The function fills the 'pointer'
x = x[0] # We dereference our 'pointer'

There's generally a better way, though (which way that is depends greatly
on the context).

Cheers,
Nick.
 
S

Steve Holden

houbahop said:
thanks, very usefull answer.





return multiple values is ok, I usualy use a function only to return one
value, for exemple : value=IsSomething(), returning true, to include that in
an if statement : if (isSomething(blabla) ) ... but It's not a problem to
change that habit. and as I have read somewhere about python : "Explicit is
better than implicit"

Plus, as you get more used to Python you'll also get used to thinking of
a tuple as a single composite object.

regards
Steve
 
F

Fredrik Lundh

Nick said:
Python could be said to pass everything by reference. You are getting caught more by the
difference between mutable and immutable types, than by the distinction between 'pass by
reference' and 'pass by value' that other languages have (Python actually uses a blend of the two
ideas - you get references passed in, but it you use assignment on your arguments, the caller is
not affected).

to avoid confusing people who (think they) know exactly what "call by value"
and "call by reference" means, the preferred term is "call by object".

for some background, see

http://mail.python.org/pipermail/python-list/2003-May/163312.html

(in earlier literature, Python's model is often called "call by sharing". this model is
in fact closer to "call by value" than "call by reference", at least if you stick to the
usual definitions)

</F>
 
A

Adam DePrince

thanks, very usefull answer.



return multiple values is ok, I usualy use a function only to return one
value, for exemple : value=IsSomething(), returning true, to include that in
an if statement : if (isSomething(blabla) ) ... but It's not a problem to
change that habit. and as I have read somewhere about python : "Explicit is
better than implicit"

Dominique.

I think your interpretation of the the "explicit vs. implicit" quote
might be confusing in this case. Certainly:

x = 0
def a():
something = 1
somethingelse = 2
global x
x = something
return somethingelse

y = a()
print x,y

To say "we are explicitly setting X" in a is wrong. We are returning 1
and 2. We return 2 explicitly. We return 1 by side effect.

If we want to explicitly return both, then:

def a():
something = 1
somethingelse = 2
return something,somethingelse

x,y = a()

This makes the code clear and easy to understand.

Navré je ne pas répondre en français.

- Adam DePrince
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top