Re: what does 'a=b=c=[]' do

2011-12-25 Thread Steven D'Aprano
On Sat, 24 Dec 2011 19:41:55 +0100, Thomas Rachel wrote:

 The only times you need the brackets around a tuple is to control the
 precedence of operations, or for an empty tuple.
 
 IBTD:
 
 a=((a, b) for a, b, c in some_iter)
 b=[(1, c) for whatever]
 
 Without the round brackets, it is a syntax error.

Correction noted.

Nevertheless, the parentheses don't create the tuple, the comma operator 
does.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Early and late binding [was Re: what does 'a=b=c=[]' do]

2011-12-24 Thread Steven D'Aprano
On Sat, 24 Dec 2011 09:50:04 +1100, Chris Angelico wrote:

 On Sat, Dec 24, 2011 at 9:32 AM, Steven D'Aprano
 steve+comp.lang.pyt...@pearwood.info wrote:
 Yes. But having to manage it *by hand* is still unclean:
 
 Well, my point was that Python's current behaviour _is_ that.

Minus the managing it by hand part.


 * you still have to assign the default value to the function assignment
 outside the function, which is inelegant;
 
 C's static variables are initialized inside the function. But since
 Python doesn't have that, it doesn't really work that way. (You might be
 able to use a decorator to do some cool tricks though.)

If Python were C, then static variables would be the right solution, but 
since it isn't, they aren't.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Early and late binding [was Re: what does 'a=b=c=[]' do]

2011-12-24 Thread Steven D'Aprano
On Fri, 23 Dec 2011 19:24:44 -0500, Devin Jeanpierre wrote:

 To fake early binding when the language provides late binding, you
 still use a sentinel value, but the initialization code creating the
 default value is outside the body of the function, usually in a global
 variable:

_DEFAULT_Y = []  # Private constant, don't touch.

def func(x, y=None):
if y is None:
y = _DEFAULT_Y
...

 This separates parts of the code that should be together, and relies on
 a global, with all the disadvantages that implies.
 
 No, you can just do def func(x, y=_DEFAULT_Y): ...

Point taken. Nevertheless, the semantics are still not the same as actual 
early binding: if the global name is deleted or changed, the function 
stops working.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Early and late binding [was Re: what does 'a=b=c=[]' do]

2011-12-24 Thread Steven D'Aprano
On Fri, 23 Dec 2011 17:03:11 +, Neil Cerutti wrote:

 The disadvantage of late binding is that since the expression is live,
 it needs to be calculated each time, even if it turns out to be the
 same result. But there's no guarantee that it will return the same
 result each time:
 
 That's its main *advantage*.

Ah yes, sorry, poor wording on my part. Whether calculating the default 
value *once* or *each time* is an advantage or disadvantage depends on 
what you're trying to do. Either way, it could be just what you want, or 
an annoying source of bugs.


 consider a default value like x=time.time(), which will return a
 different value each time it is called; or one like x=a+b, which will
 vary if either a or b are changed. Or will fail altogether if either a
 or b are deleted. This will surprise some people some of the time and
 lead to demands that Python fix the obviously buggy default
 argument gotcha.
 
 It's hard to see anyone being confused by the resultant exception.

That's because you're coming at it from the perspective of somebody who 
knows what to expect, in the middle of a discussion about the semantics 
of late binding. Now imagine you're a newbie who has never thought about 
the details of when the default value is created, but has a function like 
def foo(x, y=a+b). He calls foo(x) seven times and it works, and on the 
eighth time it blows up, perhaps with a NameError. It's surprising 
behaviour, and newbies aren't good at diagnosing surprising bugs.

Or worse, it doesn't blow up at all, but gives some invalid value that 
causes your calculations to be completely wrong. Exceptions are not the 
worst bug to have -- they are the best.


 It's
 much harder to figure out what's going wrong with an early-bound
 mutable.

Only for those who don't understand, or aren't thinking about, Python's 
object model. The behaviour of early-bound mutables is obvious and clear 
once you think about it, but it does require you to think about what's 
going on under the hood, so to speak.

[...]
 To fake early binding when the language provides late binding, you
 still use a sentinel value, but the initialization code creating the
 default value is outside the body of the function, usually in a global
 variable:
[...]
 
 I'd use a function attribute.
 
 def func(x, y=None):
   if y is None:
 y = func.default_y
   ...
 func.default_y = []
 
 That's awkward only if you believe function attributes are awkward.

I do. All you've done is move the default from *before* the function is 
defined to *after* the function is defined, instead of keeping it in the 
function definition. It's still separate, and if the function is renamed 
your code stops working. In other words, it violates encapsulation of the 
function.

That's not to say that you shouldn't do this. It's a perfectly reasonable 
technique, and I've used it myself, but it's not as elegant as the 
current Python default argument behaviour.


[...]
 The greater efficiency was probably what decided this question for
 Python, right? Since late-binding is so easy to fake, is hardly ever
 what you want, and would make all code slower, why do it?

Excellent point.


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-24 Thread Lie Ryan

On 12/22/2011 10:20 AM, Dennis Lee Bieber wrote:


which is to define the names a, b, and c, and connects the three
names to the single object (integer 7 or new empty list).


note that this connects and disconnecting business is more commonly 
referred to in python parlance as binding a name to an object.


--
http://mail.python.org/mailman/listinfo/python-list


Re: Early and late binding [was Re: what does 'a=b=c=[]' do]

2011-12-24 Thread alex23
On Dec 24, 2:27 am, Mel Wilson mwil...@the-wire.com wrote:
 In a tool that's meant for other people to use to accomplish work of their
 own, breaking workflow is a cardinal sin.

 In a research language that's meant always to be up-to-date with the concept
 of the week, not so much.

What on earth gave you the impression Python was bleeding edge? As
there's more to the language than its syntax, breaking workflow
disrupts the core library as much as it does the code of everyone
else.

More importantly, you're talking pap. Research is as much about
communication as programming; if you expect every single researcher in
a discipline (or even in the same _building_) to remain in perfect
lockstep with the version releases of a domain-relevant language,
you're either not a researcher or not a very good one. You should get
out to a conference occasionally and see what people think about your
concept of the week idea.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Early and late binding [was Re: what does 'a=b=c=[]' do]

2011-12-24 Thread alex23
On Dec 24, 2:15 am, Roy Smith r...@panix.com wrote:
 I know this is not quite the same thing, but it's interesting to look at
 what django (and mongoengine) do in their model definitions, prompted by
 your time.time() example.  You can do declare a model field something
 like:

 class Foo(models.Model):
    timestamp = DateTimeField(default=datetime.utcnow)

 Now, when you create a Foo, if you don't supply a timestamp, it
 generates one by calling utcnow() for you.  Very handy.

 I'm not arguing that Python should do that, just pointing out an example
 of where late binding is nice.

There is absolutely nothing stopping you from writing functions now
with that behaviour. All Python functions are early binding, late
calling with their arguments, if you treat the arguments as callables
within the function body.



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Early and late binding [was Re: what does 'a=b=c=[]' do]

2011-12-24 Thread alex23
On Dec 24, 6:25 pm, Steven D'Aprano steve
+comp.lang.pyt...@pearwood.info wrote:
  It's
  much harder to figure out what's going wrong with an early-bound
  mutable.

 Only for those who don't understand, or aren't thinking about, Python's
 object model. The behaviour of early-bound mutables is obvious and clear
 once you think about it, but it does require you to think about what's
 going on under the hood, so to speak.

And here we've come full circle to the point of this thread.

If Python was ever 'fixed' to prevent this issue, I'm pretty sure we'd
see an increase in the number of questions like the OP's.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-24 Thread Thomas Rachel

Am 21.12.2011 23:25 schrieb Eric:


Is it true that if I want to create an array or arbitrary size such
as:
for a in range(n):
   x.append(some function...)

I must do this instead?
x=[]
for a in range(n):
   x.append(some function...)


Of course - your x must exist before using it.

 Now to my actual question.  I need to do the above for multiple arrays

(all the same, arbitrary size).  So I do this:
x=y=z=[]
for a in range(n):
   x.append(some function...)
   y.append(some other function...)
   z.append(yet another function...)
Also, is there a more pythonic way to do x=[], y=[], z=[]?


You could do:

def create_xyz(n):
for a in range(n):
yield some function..., some other function..., \
yet another function...)

x, y, z = zip(*create_xyz(11))

or, if you want x, y, z to be lists,

x, y, z = [list(i) for i in zip(*create_xyz(11))]

.


Thomas
--
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-24 Thread Thomas Rachel

Am 22.12.2011 00:48 schrieb Steven D'Aprano:

On Wed, 21 Dec 2011 18:20:16 -0500, Dennis Lee Bieber wrote:


For the amount of typing, it's easier to just do a straight line
tuple unpack


a,b,c = ([],[],[])


Note that tuples are created by the comma, not the round brackets (or
parentheses for any Americans reading). So the round brackets there are
strictly redundant:

a, b, c = [], [], []

The only times you need the brackets around a tuple is to control the
precedence of operations, or for an empty tuple.


IBTD:

a=((a, b) for a, b, c in some_iter)
b=[(1, c) for whatever]

Without the round brackets, it is a syntax error.


Thomas
--
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-24 Thread Thomas Rachel

Am 22.12.2011 00:20 schrieb Dennis Lee Bieber:


The key one is that lists ([] defines a list, not an array) are
mutable. Your 7 is not mutable.


Strictly spoken, that's only a side show where the effect is visible.

The real key concept is that [] creates *one* object which is then 
assigned to the three names. That's the same for mutable and immutable 
objects.


But only the modification which happens on mutable objects turns it into 
a problem.


The rest o your explanation is 100% correct.


Thomas
--
http://mail.python.org/mailman/listinfo/python-list


Re: Early and late binding [was Re: what does 'a=b=c=[]' do]

2011-12-24 Thread Devin Jeanpierre
 If Python was ever 'fixed' to prevent this issue, I'm pretty sure we'd
 see an increase in the number of questions like the OP's.

What makes you so sure? Both models do make sense and are equally
valid, it's just that only one of them is true. Is it just because
people already used to Python would get confused?

-- Devin

On Sat, Dec 24, 2011 at 9:08 AM, alex23 wuwe...@gmail.com wrote:
 On Dec 24, 6:25 pm, Steven D'Aprano steve
 +comp.lang.pyt...@pearwood.info wrote:
  It's
  much harder to figure out what's going wrong with an early-bound
  mutable.

 Only for those who don't understand, or aren't thinking about, Python's
 object model. The behaviour of early-bound mutables is obvious and clear
 once you think about it, but it does require you to think about what's
 going on under the hood, so to speak.

 And here we've come full circle to the point of this thread.

 If Python was ever 'fixed' to prevent this issue, I'm pretty sure we'd
 see an increase in the number of questions like the OP's.
 --
 http://mail.python.org/mailman/listinfo/python-list
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Early and late binding [was Re: what does 'a=b=c=[]' do]

2011-12-24 Thread alex23
On Dec 25, 9:25 am, Devin Jeanpierre jeanpierr...@gmail.com wrote:
  If Python was ever 'fixed' to prevent this issue, I'm pretty sure we'd
  see an increase in the number of questions like the OP's.

 What makes you so sure? Both models do make sense and are equally
 valid, it's just that only one of them is true. Is it just because
 people already used to Python would get confused?

Because I believe that the source of confusion has far more to do with
mutable/immutable objects than with early/late binding. Masking or
'correcting' an aspect of Python's behaviour because novices make the
wrong assumption about it just pushes the problem elsewhere and
potentially makes the language inconsistent at the same time.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Early and late binding [was Re: what does 'a=b=c=[]' do]

2011-12-24 Thread Devin Jeanpierre
 Because I believe that the source of confusion has far more to do with
 mutable/immutable objects than with early/late binding. Masking or
 'correcting' an aspect of Python's behaviour because novices make the
 wrong assumption about it just pushes the problem elsewhere and
 potentially makes the language inconsistent at the same time.

That seems fairly silly -- foo.append(bar) obviously mutates
_something_ . Certainly it wasn't the source of my confusion when I
got caught on this. What makes you believe that the fundamental
confusion is about mutability?

(Also, if the change is applied everywhere, the language would not be
inconsistent.)

-- Devin

On Sat, Dec 24, 2011 at 7:10 PM, alex23 wuwe...@gmail.com wrote:
 On Dec 25, 9:25 am, Devin Jeanpierre jeanpierr...@gmail.com wrote:
  If Python was ever 'fixed' to prevent this issue, I'm pretty sure we'd
  see an increase in the number of questions like the OP's.

 What makes you so sure? Both models do make sense and are equally
 valid, it's just that only one of them is true. Is it just because
 people already used to Python would get confused?

 Because I believe that the source of confusion has far more to do with
 mutable/immutable objects than with early/late binding. Masking or
 'correcting' an aspect of Python's behaviour because novices make the
 wrong assumption about it just pushes the problem elsewhere and
 potentially makes the language inconsistent at the same time.
 --
 http://mail.python.org/mailman/listinfo/python-list
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Early and late binding [was Re: what does 'a=b=c=[]' do]

2011-12-24 Thread rusi
On Dec 25, 5:32 am, Devin Jeanpierre jeanpierr...@gmail.com wrote:
 alex23 wrote:
  Because I believe that the source of confusion has far more to do with
  mutable/immutable objects than with early/late binding. Masking or
  'correcting' an aspect of Python's behaviour because novices make the
  wrong assumption about it just pushes the problem elsewhere and
  potentially makes the language inconsistent at the same time.

Thats hitting the nail on the head.


 That seems fairly silly -- foo.append(bar) obviously mutates
 _something_ . Certainly it wasn't the source of my confusion when I
 got caught on this. What makes you believe that the fundamental
 confusion is about mutability?

The confusion is not about mutability. Its about mutability and
parameter passing being non-orthogonal.


 (Also, if the change is applied everywhere, the language would not be
 inconsistent.)

Obviously that would depend on what the change is.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Early and late binding [was Re: what does 'a=b=c=[]' do]

2011-12-24 Thread Lie Ryan

On 12/24/2011 07:25 PM, Steven D'Aprano wrote:

I'd use a function attribute.

def func(x, y=None):
   if y is None:
 y = func.default_y
   ...
func.default_y = []

That's awkward only if you believe function attributes are awkward.


I do. All you've done is move the default from *before* the function is
defined to *after* the function is defined, instead of keeping it in the
function definition. It's still separate, and if the function is renamed
your code stops working. In other words, it violates encapsulation of the
function.


Although we can solve that (default being after the function is defined) 
using a simple decorator:


def funcargs(**args):
def __decorate_with_args(func):
for k,v in args.items():
setattr(func, k, v)
return func
return __decorate_with_args

Usage:

@funcargs(foo=4)
def bar(baz):
return baz + bar.foo

et voila, we had just reinvented early binding default argument, with a 
much uglier syntax.


--
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-23 Thread rusi
On Dec 23, 7:10 am, alex23 wuwe...@gmail.com wrote:
 On Dec 22, 6:51 pm, Rolf Camps r...@roce.be wrote:

  I'm afraid it's dangerous to encourage the use of '[]' as assignment to
  a parameter in a function definition. If you use the function several
  times 'default' always points to the same list.

 I appreciate the concern, but adding a default argument guard would
 not only obscure the code. It's irrelevant, as you recognise, because
 no matter what, it's going to make copies of the default argument.

 You know what the say about foolish consistencies :)

Programming languages can have bugs as much as programs can.
A classic example is the precedence table of C which Kernighan or
Ritchie (dont remember which) admitted was wrong.

Likewise function arguments that default to mutable entities is a
known gotcha of python which is best treated as a bug in python. It
should be avoided with the suitable additional circumspection that a
language bug deserves over a program bug.

[Just my rephrasing of what Ian is saying]
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-23 Thread Ethan Furman

Ian Kelly wrote:

On Thu, Dec 22, 2011 at 7:10 PM, alex23 wuwe...@gmail.com wrote:

On Dec 22, 6:51 pm, Rolf Camps r...@roce.be wrote:

I'm afraid it's dangerous to encourage the use of '[]' as assignment to
a parameter in a function definition. If you use the function several
times 'default' always points to the same list.



I appreciate the concern, but adding a default argument guard would
not only obscure the code. It's irrelevant, as you recognise, because
no matter what, it's going to make copies of the default argument.


It's only irrelevant in the immediate context of the code you posted.
But when Joe Novice sees your code and likes it and duplicates it a
million times without receiving any warning about it, he's eventually
going to write a function that modifies its default list argument, and
he'll be in for a nasty surprise when he does.


And then he will learn about it and not make the mistake again (or if he 
does, it take much less time to figure it out).


~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-23 Thread Steven D'Aprano
On Fri, 23 Dec 2011 00:38:07 -0800, rusi wrote:

 Likewise function arguments that default to mutable entities is a known
 gotcha of python which is best treated as a bug in python.

Nonsense. It is a feature, not a bug.

Some people might argue that it is a mistake, a minor feature which 
allegedly causes more difficulties than benefits. I do not hold with that 
idea. But either way, it is not a bug to be fixed, but a deliberate 
consequence of intended semantics.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-23 Thread Ethan Furman

rusi wrote:

On Dec 23, 7:10 am, alex23 wuwe...@gmail.com wrote:

On Dec 22, 6:51 pm, Rolf Camps r...@roce.be wrote:


I'm afraid it's dangerous to encourage the use of '[]' as assignment to
a parameter in a function definition. If you use the function several
times 'default' always points to the same list.



I appreciate the concern, but adding a default argument guard would
not only obscure the code. It's irrelevant, as you recognise, because
no matter what, it's going to make copies of the default argument.

You know what the say about foolish consistencies :)


Programming languages can have bugs as much as programs can.
A classic example is the precedence table of C which Kernighan or
Ritchie (dont remember which) admitted was wrong.

Likewise function arguments that default to mutable entities is a
known gotcha of python which is best treated as a bug in python. It
should be avoided with the suitable additional circumspection that a
language bug deserves over a program bug.


That is the most ridiculous thing I have heard in a while.  Mutable 
default arguments are *not* a bug in Python.


Reminds me of a bug report a couple years back claiming multiple 
inheritence was a bug and asking it to be removed.


~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-23 Thread Chris Angelico
On Fri, Dec 23, 2011 at 7:49 PM, Ethan Furman et...@stoneleaf.us wrote:
 That is the most ridiculous thing I have heard in a while.  Mutable default
 arguments are *not* a bug in Python.

 Reminds me of a bug report a couple years back claiming multiple inheritence
 was a bug and asking it to be removed.

Both of these could arguably be called misfeaures, but not bugs.

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-23 Thread rusi
On Dec 23, 2:59 pm, Chris Angelico ros...@gmail.com wrote:
 On Fri, Dec 23, 2011 at 7:49 PM, Ethan Furman et...@stoneleaf.us wrote:
  That is the most ridiculous thing I have heard in a while.  Mutable default
  arguments are *not* a bug in Python.

  Reminds me of a bug report a couple years back claiming multiple inheritence
  was a bug and asking it to be removed.

 Both of these could arguably be called misfeatures, but not bugs.

 ChrisA

In Fortran, if the comma in the loop
DO 10 I = 1,10
is misspelt as '.' it becomes the assignment
DO10I = 1.0

Do you consider it a bug or a feature?
Does Fortran consider it a bug or feature?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-23 Thread rusi
On Dec 23, 2:39 pm, Steven D'Aprano steve
+comp.lang.pyt...@pearwood.info wrote:
 On Fri, 23 Dec 2011 00:38:07 -0800, rusi wrote:
  Likewise function arguments that default to mutable entities is a known
  gotcha of python which is best treated as a bug in python.

 Nonsense. It is a feature, not a bug.

Tsk Tsk How can python have a bug? And that too on the python mailing
list?

Others however feel differently. See Chris Rebert's
http://mail.python.org/pipermail/python-ideas/2007-January/73.html
and the links cited there.


 Some people might argue that it is a mistake, a minor feature which
 allegedly causes more difficulties than benefits. I do not hold with that
 idea. But either way, it is not a bug to be fixed, but a deliberate
 consequence of intended semantics.

I did not ask or imply that it should be 'fixed', just that language
misfeatures should be treated with extra care.
Windows uses CRLF where Unix uses LF.  Nobody could argue that this
discrepancy is of any use and nobody is about to fix it.

Of course if bug means must-fix-else-unusable then sure you are
right but then we would not be able to use most of the hardware or
software that we do.

To restate what (I think) Ian is saying:

Exploit language misfeatures cleverly in your code if you want. But
please red-flag them in mailing list posts.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-23 Thread Robert Kern

On 12/23/11 10:22 AM, rusi wrote:

On Dec 23, 2:39 pm, Steven D'Apranosteve
+comp.lang.pyt...@pearwood.info  wrote:

On Fri, 23 Dec 2011 00:38:07 -0800, rusi wrote:

Likewise function arguments that default to mutable entities is a known
gotcha of python which is best treated as a bug in python.


Nonsense. It is a feature, not a bug.


Tsk Tsk How can python have a bug? And that too on the python mailing
list?

Others however feel differently. See Chris Rebert's
http://mail.python.org/pipermail/python-ideas/2007-January/73.html
and the links cited there.



Some people might argue that it is a mistake, a minor feature which
allegedly causes more difficulties than benefits. I do not hold with that
idea. But either way, it is not a bug to be fixed, but a deliberate
consequence of intended semantics.


I did not ask or imply that it should be 'fixed', just that language
misfeatures should be treated with extra care.


Bug means, roughly, something that should be fixed not just any thing that 
has some unwanted consequences. So yes, by calling it a bug you are asking and 
implying just that. If you don't mean that, don't use the word bug.


--
Robert Kern

I have come to believe that the whole world is an enigma, a harmless enigma
 that is made terrible by our own mad attempt to interpret it as though it had
 an underlying truth.
  -- Umberto Eco

--
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-23 Thread Neil Cerutti
On 2011-12-23, Neil Cerutti ne...@norwich.edu wrote:
 Is the misfeature that Python doesn't evaluate the default
 argument expression every time you call the function? What
 would be the harm if it did?

...you know, assuming it wouldn't break existing code. ;)

-- 
Neil Cerutti
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-23 Thread Neil Cerutti
On 2011-12-23, Chris Angelico ros...@gmail.com wrote:
 On Fri, Dec 23, 2011 at 7:49 PM, Ethan Furman et...@stoneleaf.us wrote:
 That is the most ridiculous thing I have heard in a while.
 ?Mutable default arguments are *not* a bug in Python.

 Reminds me of a bug report a couple years back claiming
 multiple inheritence was a bug and asking it to be removed.

 Both of these could arguably be called misfeaures, but not
 bugs.

Is the misfeature that Python doesn't evaluate the default
argument expression every time you call the function? What would
be the harm if it did?

-- 
Neil Cerutti
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-23 Thread rusi
On Dec 23, 6:10 pm, Robert Kern robert.k...@gmail.com wrote:
 On 12/23/11 10:22 AM, rusi wrote:









  On Dec 23, 2:39 pm, Steven D'Apranosteve
  +comp.lang.pyt...@pearwood.info  wrote:
  On Fri, 23 Dec 2011 00:38:07 -0800, rusi wrote:
  Likewise function arguments that default to mutable entities is a known
  gotcha of python which is best treated as a bug in python.

  Nonsense. It is a feature, not a bug.

  Tsk Tsk How can python have a bug? And that too on the python mailing
  list?

  Others however feel differently. See Chris Rebert's
 http://mail.python.org/pipermail/python-ideas/2007-January/73.html
  and the links cited there.

  Some people might argue that it is a mistake, a minor feature which
  allegedly causes more difficulties than benefits. I do not hold with that
  idea. But either way, it is not a bug to be fixed, but a deliberate
  consequence of intended semantics.

  I did not ask or imply that it should be 'fixed', just that language
  misfeatures should be treated with extra care.

 Bug means, roughly, something that should be fixed not just any thing 
 that
 has some unwanted consequences. So yes, by calling it a bug you are asking 
 and
 implying just that. If you don't mean that, don't use the word bug.

Of course it should be fixed.  The repeated recurrence of it as a
standard gotcha as well as the python ideas list testifies to that.

Its not going to be fixed -- does not mean thats ideal, just that the
best proposed solutions cost/benefit equations are not good enough at
this point.

Case in point: I think it was around python 2.2 that there were
discussions for having a conditional operator.  GvR did not put it in
for a couple of releases not because it was a bad idea but because no
syntax was good enough.

When he finally did it, he chose a syntax which is arguably not ideal
but is the best all-things-considered (eg no unnecessary new keywords,
compatibility with existing code etc)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-23 Thread Robert Kern

On 12/23/11 1:23 PM, rusi wrote:

On Dec 23, 6:10 pm, Robert Kernrobert.k...@gmail.com  wrote:

On 12/23/11 10:22 AM, rusi wrote:

On Dec 23, 2:39 pm, Steven D'Apranosteve
+comp.lang.pyt...@pearwood.infowrote:



Some people might argue that it is a mistake, a minor feature which
allegedly causes more difficulties than benefits. I do not hold with that
idea. But either way, it is not a bug to be fixed, but a deliberate
consequence of intended semantics.



I did not ask or imply that it should be 'fixed', just that language
misfeatures should be treated with extra care.


Bug means, roughly, something that should be fixed not just any thing that
has some unwanted consequences. So yes, by calling it a bug you are asking and
implying just that. If you don't mean that, don't use the word bug.


Of course it should be fixed.  The repeated recurrence of it as a
standard gotcha as well as the python ideas list testifies to that.


So you were lying when you said that you did not ask or imply that it should be 
'fixed'? Please make up your mind. It's quite rude to defend your position by 
constantly shifting it whenever you get challenged on it.


--
Robert Kern

I have come to believe that the whole world is an enigma, a harmless enigma
 that is made terrible by our own mad attempt to interpret it as though it had
 an underlying truth.
  -- Umberto Eco

--
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-23 Thread rusi
On Dec 23, 6:53 pm, Robert Kern robert.k...@gmail.com wrote:
 On 12/23/11 1:23 PM, rusi wrote:









  On Dec 23, 6:10 pm, Robert Kernrobert.k...@gmail.com  wrote:
  On 12/23/11 10:22 AM, rusi wrote:
  On Dec 23, 2:39 pm, Steven D'Apranosteve
  +comp.lang.pyt...@pearwood.info    wrote:
  Some people might argue that it is a mistake, a minor feature which
  allegedly causes more difficulties than benefits. I do not hold with that
  idea. But either way, it is not a bug to be fixed, but a deliberate
  consequence of intended semantics.

  I did not ask or imply that it should be 'fixed', just that language
  misfeatures should be treated with extra care.

  Bug means, roughly, something that should be fixed not just any thing 
  that
  has some unwanted consequences. So yes, by calling it a bug you are 
  asking and
  implying just that. If you don't mean that, don't use the word bug.

  Of course it should be fixed.  The repeated recurrence of it as a
  standard gotcha as well as the python ideas list testifies to that.

 So you were lying when you said that you did not ask or imply that it should 
 be
 'fixed'? Please make up your mind. It's quite rude to defend your position 
 by
 constantly shifting it whenever you get challenged on it.

Meanings of should http://www.englishpage.com/modals/should.html
My first should was the 3rd one
My second was the 1st one.

[And we really should stop this argument (2nd one)]
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-23 Thread Steven D'Aprano
On Fri, 23 Dec 2011 06:57:02 -0800, rusi wrote:

 On Dec 23, 6:53 pm, Robert Kern robert.k...@gmail.com wrote:
 On 12/23/11 1:23 PM, rusi wrote:
[...]
  Of course it should be fixed.  The repeated recurrence of it as a
  standard gotcha as well as the python ideas list testifies to that.

 So you were lying when you said that you did not ask or imply that it
 should be 'fixed'? Please make up your mind. It's quite rude to
 defend your position by constantly shifting it whenever you get
 challenged on it.
 
 Meanings of should http://www.englishpage.com/modals/should.html My
 first should was the 3rd one
 My second was the 1st one.

Rusi, are you a native English speaker? Because that excuse/defense does 
not excuse your comments at all, multiple meanings of should or not. 
Why not just admit to a mistake? After denying you were asking for Python 
to fix a so-called bug, you then called for Python to fix it. If this 
were a real argument rather than a friendly debate, people would be 
crying Gotcha! for sure.


 [And we really should stop this argument (2nd one)]

When the facts are against you, argue semantics; when semantics are 
against you, argue the facts; when both are against you, claim to be 
above arguing.


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Early and late binding [was Re: what does 'a=b=c=[]' do]

2011-12-23 Thread Steven D'Aprano
On Fri, 23 Dec 2011 13:13:38 +, Neil Cerutti wrote:

 On 2011-12-23, Neil Cerutti ne...@norwich.edu wrote:
 Is the misfeature that Python doesn't evaluate the default argument
 expression every time you call the function? What would be the harm if
 it did?
 
 ...you know, assuming it wouldn't break existing code. ;)

It will. Python's default argument strategy has been in use for 20 years. 
Some code will rely on it. I know mine does.

There are two strategies for dealing with default arguments that I know 
of: early binding and late binding. Python has early binding: the default 
argument is evaluated once, when the function is created. Late binding 
means the default argument is always re-evaluated each time it is needed.

Both strategies are reasonable choices. Both have advantages and 
disadvantages. Both have use-cases, and both lead to confusion when the 
user expects one but gets the other. If you think changing from early to 
late binding will completely eliminate the default argument gotcha, you 
haven't thought things through -- at best you might reduce the number of 
complaints, but only at the cost of shifting them from one set of use-
cases to another.

Early binding is simple to implement and simple to explain: when you 
define a function, the default value is evaluated once, and the result 
stored to be used whenever it is needed. The disadvantage is that it can 
lead to unexpected results for mutable arguments.

Late binding is also simple to explain, but a little harder to implement. 
The function needs to store the default value as a piece of code (an 
expression) which can be re-evaluated as often as needed, not an object.

The disadvantage of late binding is that since the expression is live, it 
needs to be calculated each time, even if it turns out to be the same 
result. But there's no guarantee that it will return the same result each 
time: consider a default value like x=time.time(), which will return a 
different value each time it is called; or one like x=a+b, which will 
vary if either a or b are changed. Or will fail altogether if either a or 
b are deleted. This will surprise some people some of the time and lead 
to demands that Python fix the obviously buggy default argument 
gotcha.

If a language only offers one, I maintain it should offer early binding 
(the status quo). Why? Because it is more elegant to fake late binding in 
an early binding language than vice versa.

To fake late binding in a language with early binding, use a sentinel 
value and put the default value inside the body of the function:

def func(x, y=None):
if y is None:
y = []
...

All the important parts of the function are in one place, namely inside 
the function.

To fake early binding when the language provides late binding, you still 
use a sentinel value, but the initialization code creating the default 
value is outside the body of the function, usually in a global variable:

_DEFAULT_Y = []  # Private constant, don't touch.

def func(x, y=None):
if y is None:
y = _DEFAULT_Y
...

This separates parts of the code that should be together, and relies on a 
global, with all the disadvantages that implies.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Early and late binding [was Re: what does 'a=b=c=[]' do]

2011-12-23 Thread Chris Angelico
On Sat, Dec 24, 2011 at 2:49 AM, Steven D'Aprano
steve+comp.lang.pyt...@pearwood.info wrote:
 To fake early binding when the language provides late binding, you still
 use a sentinel value, but the initialization code creating the default
 value is outside the body of the function, usually in a global variable:

    _DEFAULT_Y = []  # Private constant, don't touch.

    def func(x, y=None):
        if y is None:
            y = _DEFAULT_Y
        ...

 This separates parts of the code that should be together, and relies on a
 global, with all the disadvantages that implies.

A static variable (in the C sense) would make this just as clean as
the alternative. In Python, that could be implemented as an attribute
of the function object. Oh looky here... that's how default arguments
are implemented. :)

Tim Toady.

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-23 Thread rusi
On Dec 23, 8:33 pm, Steven D'Aprano steve
+comp.lang.pyt...@pearwood.info wrote:
 On Fri, 23 Dec 2011 06:57:02 -0800, rusi wrote:
  On Dec 23, 6:53 pm, Robert Kern robert.k...@gmail.com wrote:
  On 12/23/11 1:23 PM, rusi wrote:
 [...]
   Of course it should be fixed.  The repeated recurrence of it as a
   standard gotcha as well as the python ideas list testifies to that.

  So you were lying when you said that you did not ask or imply that it
  should be 'fixed'? Please make up your mind. It's quite rude to
  defend your position by constantly shifting it whenever you get
  challenged on it.

  Meanings of shouldhttp://www.englishpage.com/modals/should.htmlMy
  first should was the 3rd one
  My second was the 1st one.

 Rusi, are you a native English speaker? Because that excuse/defense does
 not excuse your comments at all, multiple meanings of should or not.
 Why not just admit to a mistake? After denying you were asking for Python
 to fix a so-called bug, you then called for Python to fix it. If this
 were a real argument rather than a friendly debate, people would be
 crying Gotcha! for sure.

Ok You got me!

Does that help the OP's?

 It's a slick language but I still have trouble wrapping my brain around some 
 of the concepts.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Early and late binding [was Re: what does 'a=b=c=[]' do]

2011-12-23 Thread Roy Smith
In article 4ef4a30d$0$29973$c3e8da3$54964...@news.astraweb.com,
 Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote:

 The disadvantage of late binding is that since the expression is live, it 
 needs to be calculated each time, even if it turns out to be the same 
 result. But there's no guarantee that it will return the same result each 
 time: consider a default value like x=time.time(), which will return a 
 different value each time it is called

I know this is not quite the same thing, but it's interesting to look at 
what django (and mongoengine) do in their model definitions, prompted by 
your time.time() example.  You can do declare a model field something 
like:

class Foo(models.Model):
   timestamp = DateTimeField(default=datetime.utcnow)

Now, when you create a Foo, if you don't supply a timestamp, it 
generates one by calling utcnow() for you.  Very handy.

I'm not arguing that Python should do that, just pointing out an example 
of where late binding is nice.  Technically, that's probably not really 
late binding.  You always get the same function bound, it's just called 
each time it's used because django notices that you passed a callable.  
Maybe sort of early binding, late calling would be a more apt 
description, but given that python has descriptors, the line between 
data and function sometimes gets a little blurry anyway.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Early and late binding [was Re: what does 'a=b=c=[]' do]

2011-12-23 Thread Mel Wilson
Steven D'Aprano wrote:
 On Fri, 23 Dec 2011 13:13:38 +, Neil Cerutti wrote:
 On 2011-12-23, Neil Cerutti ne...@norwich.edu wrote:
 ...you know, assuming it wouldn't break existing code. ;)
 
 It will. Python's default argument strategy has been in use for 20 years.
 Some code will rely on it. I know mine does.

In a tool that's meant for other people to use to accomplish work of their 
own, breaking workflow is a cardinal sin.

In a research language that's meant always to be up-to-date with the concept 
of the week, not so much.

Mel.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Early and late binding [was Re: what does 'a=b=c=[]' do]

2011-12-23 Thread Neil Cerutti
On 2011-12-23, Steven D'Aprano steve+comp.lang.pyt...@pearwood.info wrote:
 On Fri, 23 Dec 2011 13:13:38 +, Neil Cerutti wrote:
 On 2011-12-23, Neil Cerutti ne...@norwich.edu wrote:
 Is the misfeature that Python doesn't evaluate the default
 argument expression every time you call the function? What
 would be the harm if it did?
 
 ...you know, assuming it wouldn't break existing code. ;)

 It will. Python's default argument strategy has been in use for
 20 years. Some code will rely on it. I know mine does.

I'm aware of that. I should have put the question differently,
but you did guess what I meant to ask. Thanks for the dicussion.

 Early binding is simple to implement and simple to explain:
 when you define a function, the default value is evaluated
 once, and the result stored to be used whenever it is needed.
 The disadvantage is that it can lead to unexpected results for
 mutable arguments.

 Late binding is also simple to explain, but a little harder to
 implement. The function needs to store the default value as a
 piece of code (an expression) which can be re-evaluated as
 often as needed, not an object.

 The disadvantage of late binding is that since the expression
 is live, it needs to be calculated each time, even if it turns
 out to be the same result. But there's no guarantee that it
 will return the same result each time: 

That's its main *advantage*.

 consider a default value like x=time.time(), which will return
 a different value each time it is called; or one like x=a+b,
 which will vary if either a or b are changed. Or will fail
 altogether if either a or b are deleted. This will surprise
 some people some of the time and lead to demands that Python
 fix the obviously buggy default argument gotcha.

It's hard to see anyone being confused by the resultant
exception. It's much harder to figure out what's going wrong with
an early-bound mutable.

 If a language only offers one, I maintain it should offer early
 binding (the status quo). Why? Because it is more elegant to
 fake late binding in an early binding language than vice versa.

 To fake late binding in a language with early binding, use a
 sentinel value and put the default value inside the body of the
 function:

 def func(x, y=None):
 if y is None:
 y = []
 ...

 All the important parts of the function are in one place,
 namely inside the function.

 To fake early binding when the language provides late binding,
 you still use a sentinel value, but the initialization code
 creating the default value is outside the body of the function,
 usually in a global variable:

 _DEFAULT_Y = []  # Private constant, don't touch.

 def func(x, y=None):
 if y is None:
 y = _DEFAULT_Y
 ...

 This separates parts of the code that should be together, and
 relies on a global, with all the disadvantages that implies.

I'd use a function attribute.

def func(x, y=None):
  if y is None:
y = func.default_y
  ...
func.default_y = []

That's awkward only if you believe function attributes are
awkward. Even if common practice were instead to use a global
variable, as you did, it wouldn't be considered bad if it were a
common idiom. In case, a global that's not meant to be rebound or
mutated is the best possible variety.

However, I also wouldn't base the decision of late versus early
binding on how confusing it would be if you assume wrongly which
one you are getting. Most default function arguments are
literals, so in Python the question just doesn't come up until
you get mutabled.

The greater efficiency was probably what decided this question
for Python, right? Since late-binding is so easy to fake, is
hardly ever what you want, and would make all code slower, why do
it?

-- 
Neil Cerutti
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-23 Thread Michael Torrie
On 12/23/2011 03:31 AM, rusi wrote:
 In Fortran, if the comma in the loop
 DO 10 I = 1,10
 is misspelt as '.' it becomes the assignment
 DO10I = 1.0
 
 Do you consider it a bug or a feature?
 Does Fortran consider it a bug or feature?

Non sequitor.  Nothing at all to do with the issue at hand.
Furthermore, you are talking about a parser feature not a runtime
behavior.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Early and late binding [was Re: what does 'a=b=c=[]' do]

2011-12-23 Thread Steven D'Aprano
On Sat, 24 Dec 2011 02:55:41 +1100, Chris Angelico wrote:

 On Sat, Dec 24, 2011 at 2:49 AM, Steven D'Aprano
 steve+comp.lang.pyt...@pearwood.info wrote:
 To fake early binding when the language provides late binding, you
 still use a sentinel value, but the initialization code creating the
 default value is outside the body of the function, usually in a global
 variable:

    _DEFAULT_Y = []  # Private constant, don't touch.

    def func(x, y=None):
        if y is None:
            y = _DEFAULT_Y
        ...

 This separates parts of the code that should be together, and relies on
 a global, with all the disadvantages that implies.
 
 A static variable (in the C sense) would make this just as clean as the
 alternative. In Python, that could be implemented as an attribute of the
 function object. Oh looky here... that's how default arguments are
 implemented. :)

Yes. But having to manage it *by hand* is still unclean:

* you still have to assign the default value to the function assignment 
outside the function, which is inelegant; 

* if you rename the function, the internal lookup func.default_value will 
fail.

I'm not saying it can't be done. I'm just saying that the status quo is 
cleaner and more elegant, and if you want late binding, there is a 
simple, obvious, elegant idiom to get it.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Early and late binding [was Re: what does 'a=b=c=[]' do]

2011-12-23 Thread Chris Angelico
On Sat, Dec 24, 2011 at 9:32 AM, Steven D'Aprano
steve+comp.lang.pyt...@pearwood.info wrote:
 Yes. But having to manage it *by hand* is still unclean:

Well, my point was that Python's current behaviour _is_ that.

 * you still have to assign the default value to the function assignment
 outside the function, which is inelegant;

C's static variables are initialized inside the function. But since
Python doesn't have that, it doesn't really work that way. (You might
be able to use a decorator to do some cool tricks though.)

 * if you rename the function, the internal lookup func.default_value will
 fail.

Python would benefit some from a current-function reference, if
tricks like this were to be encouraged. It'd help with recursion too.
h...

 def Y(func):
return lambda *args,**kwargs: func(func,*args,**kwargs)

 @Y
def foo(me,x):
if x5: return x
return me(me,x+1),7,x

 foo(3)
(((6, 7, 5), 7, 4), 7, 3)

Useful? Not very. Maybe as a language feature, but not as a parameter.
But of curiosity value.

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Early and late binding [was Re: what does 'a=b=c=[]' do]

2011-12-23 Thread Devin Jeanpierre
 To fake early binding when the language provides late binding, you still
 use a sentinel value, but the initialization code creating the default
 value is outside the body of the function, usually in a global variable:

_DEFAULT_Y = []  # Private constant, don't touch.

def func(x, y=None):
if y is None:
y = _DEFAULT_Y
...

 This separates parts of the code that should be together, and relies on a
 global, with all the disadvantages that implies.

No, you can just do def func(x, y=_DEFAULT_Y): ...

-- Devin

On Fri, Dec 23, 2011 at 10:49 AM, Steven D'Aprano
steve+comp.lang.pyt...@pearwood.info wrote:
 On Fri, 23 Dec 2011 13:13:38 +, Neil Cerutti wrote:

 On 2011-12-23, Neil Cerutti ne...@norwich.edu wrote:
 Is the misfeature that Python doesn't evaluate the default argument
 expression every time you call the function? What would be the harm if
 it did?

 ...you know, assuming it wouldn't break existing code. ;)

 It will. Python's default argument strategy has been in use for 20 years.
 Some code will rely on it. I know mine does.

 There are two strategies for dealing with default arguments that I know
 of: early binding and late binding. Python has early binding: the default
 argument is evaluated once, when the function is created. Late binding
 means the default argument is always re-evaluated each time it is needed.

 Both strategies are reasonable choices. Both have advantages and
 disadvantages. Both have use-cases, and both lead to confusion when the
 user expects one but gets the other. If you think changing from early to
 late binding will completely eliminate the default argument gotcha, you
 haven't thought things through -- at best you might reduce the number of
 complaints, but only at the cost of shifting them from one set of use-
 cases to another.

 Early binding is simple to implement and simple to explain: when you
 define a function, the default value is evaluated once, and the result
 stored to be used whenever it is needed. The disadvantage is that it can
 lead to unexpected results for mutable arguments.

 Late binding is also simple to explain, but a little harder to implement.
 The function needs to store the default value as a piece of code (an
 expression) which can be re-evaluated as often as needed, not an object.

 The disadvantage of late binding is that since the expression is live, it
 needs to be calculated each time, even if it turns out to be the same
 result. But there's no guarantee that it will return the same result each
 time: consider a default value like x=time.time(), which will return a
 different value each time it is called; or one like x=a+b, which will
 vary if either a or b are changed. Or will fail altogether if either a or
 b are deleted. This will surprise some people some of the time and lead
 to demands that Python fix the obviously buggy default argument
 gotcha.

 If a language only offers one, I maintain it should offer early binding
 (the status quo). Why? Because it is more elegant to fake late binding in
 an early binding language than vice versa.

 To fake late binding in a language with early binding, use a sentinel
 value and put the default value inside the body of the function:

    def func(x, y=None):
        if y is None:
            y = []
        ...

 All the important parts of the function are in one place, namely inside
 the function.

 To fake early binding when the language provides late binding, you still
 use a sentinel value, but the initialization code creating the default
 value is outside the body of the function, usually in a global variable:

    _DEFAULT_Y = []  # Private constant, don't touch.

    def func(x, y=None):
        if y is None:
            y = _DEFAULT_Y
        ...

 This separates parts of the code that should be together, and relies on a
 global, with all the disadvantages that implies.



 --
 Steven
 --
 http://mail.python.org/mailman/listinfo/python-list
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-22 Thread Rolf Camps
alex23 schreef op wo 21-12-2011 om 16:50 [-0800]:
 On Dec 22, 8:25 am, Eric einazaki...@yahoo.com wrote:
  This surprises me, can someone tell me why it shouldn't?  I figure if
  I want to create and initialize three scalars the just do a=b=c=7,
  for example, so why not extend it to arrays.
 
 The thing to remember is that everything is an object, and that it's
 better to think of variables as labels on an object.
 
 So: a=b=c=7 means that _one_ integer object with the value of 7 can be
 referenced using any of the labels a, b or c. x=y=z=[] means that
 _one_ empty list can be referenced using x, y or z.
 
 The difference is that the value of a number object _cannot be
 changed_ ('immutable') while a list can be modified to add or remove
 items ('mutable'). a=10 just reassigns the label a to an integer
 object of value 10. x.append(foo) _modifies_ the list referred to by
 x, which is the same list known as y  z.
 
  Also, is there a more pythonic way to do x=[], y=[], z=[]?
 
 I'd say that _is_ the most pythonic way, it's very obvious in its
 intent (or would be with appropriate names). If it bothers you that
 much:
 
 def listgen(count, default=[]):
 for _ in xrange(count):
 yield default[:]
 
 x, y, z = listgen(3)
 


I'm afraid it's dangerous to encourage the use of '[]' as assignment to
a parameter in a function definition. If you use the function several
times 'default' always points to the same list. 

 def return_list(list_ = []):
 return list_
 a_list = return_list()
 a_list
[]
 a_list.append(3)
 a_list
[3]
 b_list = return_list()
 b_list
 [3]   # !!??

 def return_list():
 return []
 a_list = return_list()
 a_list
[]
 a_list.append(3)
 a_list
[3]
 b_list = return_list()
 b_list
 []# OK!

I only use python3 so I don't know how these things work in other
versions.

No problem in your function since you yield a copy, but I've already
seen long threads about this.

I would change your function to (Python3.x):

def empty_lists(count):
for _ in range(count):
yield []


Regards,

Rolf




-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-22 Thread Ethan Furman

Rolf Camps wrote:

alex23 schreef op wo 21-12-2011 om 16:50 [-0800]:

I'd say that _is_ the most pythonic way, it's very obvious in its
intent (or would be with appropriate names). If it bothers you that
much:

def listgen(count, default=[]):
for _ in xrange(count):
yield default[:]

x, y, z = listgen(3)


I would change your function to (Python3.x):

def empty_lists(count):
for _ in range(count):
yield []


While it's good to be careful, default mutable arguments have their 
place.  Alex's versioun allows one to use an already existing list and 
get shallow copies of it, yours will only create empty lists.


a, b, c = listgen([1, 2, 3])
# a, b,  c are bound to different lists

~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-22 Thread alex23
On Dec 22, 6:51 pm, Rolf Camps r...@roce.be wrote:
 I'm afraid it's dangerous to encourage the use of '[]' as assignment to
 a parameter in a function definition. If you use the function several
 times 'default' always points to the same list.

I appreciate the concern, but adding a default argument guard would
not only obscure the code. It's irrelevant, as you recognise, because
no matter what, it's going to make copies of the default argument.

You know what the say about foolish consistencies :)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-22 Thread Ian Kelly
On Thu, Dec 22, 2011 at 7:10 PM, alex23 wuwe...@gmail.com wrote:
 On Dec 22, 6:51 pm, Rolf Camps r...@roce.be wrote:
 I'm afraid it's dangerous to encourage the use of '[]' as assignment to
 a parameter in a function definition. If you use the function several
 times 'default' always points to the same list.

 I appreciate the concern, but adding a default argument guard would
 not only obscure the code. It's irrelevant, as you recognise, because
 no matter what, it's going to make copies of the default argument.

It's only irrelevant in the immediate context of the code you posted.
But when Joe Novice sees your code and likes it and duplicates it a
million times without receiving any warning about it, he's eventually
going to write a function that modifies its default list argument, and
he'll be in for a nasty surprise when he does.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-22 Thread Eric
On Dec 21, 6:50 pm, alex23 wuwe...@gmail.com wrote:
 On Dec 22, 8:25 am, Eric einazaki...@yahoo.com wrote:

  This surprises me, can someone tell me why it shouldn't?  I figure if
  I want to create and initialize three scalars the just do a=b=c=7,
  for example, so why not extend it to arrays.

 The thing to remember is that everything is an object, and that it's
 better to think of variables as labels on an object.

 So: a=b=c=7 means that _one_ integer object with the value of 7 can be
 referenced using any of the labels a, b or c. x=y=z=[] means that
 _one_ empty list can be referenced using x, y or z.

 The difference is that the value of a number object _cannot be
 changed_ ('immutable') while a list can be modified to add or remove
 items ('mutable'). a=10 just reassigns the label a to an integer
 object of value 10. x.append(foo) _modifies_ the list referred to by
 x, which is the same list known as y  z.



  Also, is there a more pythonic way to do x=[], y=[], z=[]?

 I'd say that _is_ the most pythonic way, it's very obvious in its
 intent (or would be with appropriate names). If it bothers you that
 much:


Thanks for the explanation.  I guess from what I've seen of Python
so far I was expecting something more, I don't know, compact.
Anyway, it doesn't bother me, at least not enough to go and do
something like this:

     def listgen(count, default=[]):
         for _ in xrange(count):
             yield default[:]

     x, y, z = listgen(3)

Thanks,
eric


-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-22 Thread alex23
On Dec 23, 12:59 pm, Ian Kelly ian.g.ke...@gmail.com wrote:
 It's only irrelevant in the immediate context of the code you posted.
 But when Joe Novice sees your code and likes it and duplicates it a
 million times

I'm sorry, but I'm not going to modify my coding style for the sake of
bad programmers.

The context is _important_. Why should I guard against default
argument mutability when its not going to occur in the function body?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-22 Thread Chris Angelico
On Fri, Dec 23, 2011 at 2:40 PM, alex23 wuwe...@gmail.com wrote:
 I'm sorry, but I'm not going to modify my coding style for the sake of
 bad programmers.

And there, folks, you have one of the eternal dilemmas. The correct
decision depends on myriad factors; if you're writing code to go into
the documentation as an example, you want it to be able to handle
idiots hacking on it - but on the other hand, that same situation
demands simplicity, which is why a lot of examples omit huge slabs of
error checking.

ChrisA
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-22 Thread Eric
On Dec 21, 5:44 pm, Steven D'Aprano steve
+comp.lang.pyt...@pearwood.info wrote:

 Yes, you should create your lists before trying to append to them.

 But you aren't forced to use a for-loop. You can use a list comprehension:

 x = [some_function(a) for a in range(n)]

 Notice that here you don't need x to pre-exist, because the list comp
 creates a brand new list, which then gets assigned directly to x.

  Now to my actual question.  I need to do the above for multiple arrays
  (all the same, arbitrary size).  So I do this:
     x=y=z=[]

 This creates one empty list object, and gives it three names, x, y and z.
 Every time you append to the list, all three names see the same change,
 because they refer to a single list.

 [...]

  Except it seems that I didn't create three different arrays, I created
  one array that goes by three different names (i.e. x[], y[] and z[] all
  reference the same pile of numbers, no idea which pile).

 Exactly.

  This surprises me, can someone tell me why it shouldn't?

 Because that's the way Python works. Python is an object-oriented, name
 binding language. This is how OO name binding works: you have a single
 object, with three names bound to it. The above line is short-cut for:

 a = []
 b = a
 c = a

 Python does not make a copy of the list unless you specifically instruct
 it to.

  I figure if I
  want to create and initialize three scalars the just do a=b=c=7,

 That creates a single integer object with value 7, and binds three names
 to it, *exactly* the same as the above.

 If you could modify int objects in place, like you can modify lists in
 place, you would see precisely the same effect. But ints are immutable:
 all operations on ints create new ints. Lists are mutable, and can be
 changed in place.

  for
  example, so why not extend it to arrays.  Also, is there a more pythonic
  way to do x=[], y=[], z=[]?

 Well that literally won't work, you can't separate them by commas.
 Newlines or semicolons will work.

 Or: x, y, z = [], [], []

 Either is pretty Pythonic.

 --
 Steven

Thanks to you and Dennis for the quick lesson and tips.  Very helpful
and illuminating.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-22 Thread Ian Kelly
On Thu, Dec 22, 2011 at 8:40 PM, alex23 wuwe...@gmail.com wrote:
 On Dec 23, 12:59 pm, Ian Kelly ian.g.ke...@gmail.com wrote:
 It's only irrelevant in the immediate context of the code you posted.
 But when Joe Novice sees your code and likes it and duplicates it a
 million times

 I'm sorry, but I'm not going to modify my coding style for the sake of
 bad programmers.

Nobody is asking you to modify your coding style.  The request is that
you not throw it up as an example without mentioning the important
caveats.

Also, novice programmer == bad programmer?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-22 Thread alex23
On Dec 23, 3:22 pm, Ian Kelly ian.g.ke...@gmail.com wrote:
 Nobody is asking you to modify your coding style.  The request is that
 you not throw it up as an example without mentioning the important
 caveats.

No, 100% no. It's not my responsibility to mention every potentially
relevant gotcha when providing example code.

 Also, novice programmer == bad programmer?

If they're wholly learning how to code by throwaway examples on
mailing lists, then yes. Object mutability is a _major_ aspect of
Python; I'm simply not going to inject an essay explaining what that
implies every time I choose to use a mutable default argument.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-21 Thread Joshua Landau
On 21 December 2011 22:25, Eric einazaki...@yahoo.com wrote:

 Is it true that if I want to create an array or arbitrary size such
 as:
   for a in range(n):
  x.append(some function...)

 I must do this instead?
   x=[]
   for a in range(n):
  x.append(some function...)

 Now to my actual question.  I need to do the above for multiple arrays
 (all the same, arbitrary size).  So I do this:
   x=y=z=[]
   for a in range(n):
  x.append(some function...)
  y.append(some other function...)
  z.append(yet another function...)

 Except it seems that I didn't create three different arrays, I created
 one array that goes by three different names (i.e. x[], y[] and z[]
 all reference the same pile of numbers, no idea which pile).

 This surprises me, can someone tell me why it shouldn't?  I figure if
 I want to create and initialize three scalars the just do a=b=c=7,


7 is 7 = True
They're the same 7. You won't notice it though, as numbers are immutable.

for example, so why not extend it to arrays.  Also, is there a more
 pythonic way to do x=[], y=[], z=[]?


 a, b, c = [], [], []

It's a slick language but I still have trouble wrapping my brain
 around some of the concepts.

 TIA,
 eric
 --
 http://mail.python.org/mailman/listinfo/python-list

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-21 Thread Chris Kaynor
On Wed, Dec 21, 2011 at 2:25 PM, Eric einazaki...@yahoo.com wrote:

 Is it true that if I want to create an array or arbitrary size such
 as:
   for a in range(n):
  x.append(some function...)

 I must do this instead?
   x=[]
   for a in range(n):
  x.append(some function...)

You can also use a list comprehension:

x = [some function... for a in range(n)]

Or extend and a generator expression:

x = []

x.extend(some function... for a in range(n))

Or map and a generator function:

map(x.append, (some function... for a in range(n)))


I would recommend either your way, the first of, or the second of my ways,
depending on the full context.



 Now to my actual question.  I need to do the above for multiple arrays
 (all the same, arbitrary size).  So I do this:
   x=y=z=[]

This creates a new object, then assigns the labels x, y, and z to that
object.

   for a in range(n):
  x.append(some function...)
  y.append(some other function...)
  z.append(yet another function...)

Then this appends the items to each of those labels, which, as they
pointing to the same object, appends to all of the labels. The variables
in Python are merely labels, and assigning to different labels does not
automatically copy the object.

Consider:
a = []
b = a
a.append(1)
print b

[1]



 Except it seems that I didn't create three different arrays, I created
 one array that goes by three different names (i.e. x[], y[] and z[]
 all reference the same pile of numbers, no idea which pile).

 This surprises me, can someone tell me why it shouldn't?  I figure if
 I want to create and initialize three scalars the just do a=b=c=7,
 for example, so why not extend it to arrays.  Also, is there a more
 pythonic way to do x=[], y=[], z=[]?

The above rules apply in all cases, however are generally invisible on
immutable objects (strings, ints, floats, tuples). In the case of a=b=c=7,
you will find that all of a, b, and c point to the same object (try the
id function or is operator). Doing the operation a += 1 after a=7 will
create a new int* with the value 7+1 and assign it to the label a.

* In CPython, there exists an optimization where small ints are cached,
namely from -7 to 255 (the lower bound I stated may be wrong). This
improved performance in most cases, but is CPython specific - other
implementations such as PyPy or IronPython may behave differently.


 It's a slick language but I still have trouble wrapping my brain
 around some of the concepts.

 TIA,
 eric
 --
 http://mail.python.org/mailman/listinfo/python-list
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-21 Thread Steven D'Aprano
On Wed, 21 Dec 2011 14:25:17 -0800, Eric wrote:

 Is it true that if I want to create an array or arbitrary size such as:
for a in range(n):
   x.append(some function...)

x is not defined, so you will get a NameError unless by some lucky fluke 
something else has created x AND it happens to be a list. Either way, it 
is unlikely to do what you want.


 I must do this instead?
x=[]
for a in range(n):
   x.append(some function...)

Yes, you should create your lists before trying to append to them.

But you aren't forced to use a for-loop. You can use a list comprehension:

x = [some_function(a) for a in range(n)]

Notice that here you don't need x to pre-exist, because the list comp 
creates a brand new list, which then gets assigned directly to x.


 Now to my actual question.  I need to do the above for multiple arrays
 (all the same, arbitrary size).  So I do this:
x=y=z=[]

This creates one empty list object, and gives it three names, x, y and z. 
Every time you append to the list, all three names see the same change, 
because they refer to a single list.

[...]
 Except it seems that I didn't create three different arrays, I created
 one array that goes by three different names (i.e. x[], y[] and z[] all
 reference the same pile of numbers, no idea which pile).

Exactly.

 This surprises me, can someone tell me why it shouldn't? 

Because that's the way Python works. Python is an object-oriented, name 
binding language. This is how OO name binding works: you have a single 
object, with three names bound to it. The above line is short-cut for:

a = []
b = a
c = a

Python does not make a copy of the list unless you specifically instruct 
it to.


 I figure if I
 want to create and initialize three scalars the just do a=b=c=7, 

That creates a single integer object with value 7, and binds three names 
to it, *exactly* the same as the above.

If you could modify int objects in place, like you can modify lists in 
place, you would see precisely the same effect. But ints are immutable: 
all operations on ints create new ints. Lists are mutable, and can be 
changed in place.

 for
 example, so why not extend it to arrays.  Also, is there a more pythonic
 way to do x=[], y=[], z=[]?

Well that literally won't work, you can't separate them by commas. 
Newlines or semicolons will work.

Or: x, y, z = [], [], []

Either is pretty Pythonic.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-21 Thread Steven D'Aprano
On Wed, 21 Dec 2011 18:20:16 -0500, Dennis Lee Bieber wrote:

   For the amount of typing, it's easier to just do a straight line
 tuple unpack
 
 a,b,c = ([],[],[])

Note that tuples are created by the comma, not the round brackets (or 
parentheses for any Americans reading). So the round brackets there are 
strictly redundant:

a, b, c = [], [], []

The only times you need the brackets around a tuple is to control the 
precedence of operations, or for an empty tuple.


-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: what does 'a=b=c=[]' do

2011-12-21 Thread alex23
On Dec 22, 8:25 am, Eric einazaki...@yahoo.com wrote:
 This surprises me, can someone tell me why it shouldn't?  I figure if
 I want to create and initialize three scalars the just do a=b=c=7,
 for example, so why not extend it to arrays.

The thing to remember is that everything is an object, and that it's
better to think of variables as labels on an object.

So: a=b=c=7 means that _one_ integer object with the value of 7 can be
referenced using any of the labels a, b or c. x=y=z=[] means that
_one_ empty list can be referenced using x, y or z.

The difference is that the value of a number object _cannot be
changed_ ('immutable') while a list can be modified to add or remove
items ('mutable'). a=10 just reassigns the label a to an integer
object of value 10. x.append(foo) _modifies_ the list referred to by
x, which is the same list known as y  z.

 Also, is there a more pythonic way to do x=[], y=[], z=[]?

I'd say that _is_ the most pythonic way, it's very obvious in its
intent (or would be with appropriate names). If it bothers you that
much:

def listgen(count, default=[]):
for _ in xrange(count):
yield default[:]

x, y, z = listgen(3)

-- 
http://mail.python.org/mailman/listinfo/python-list