Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #32748 > unrolled thread

Multi-dimensional list initialization

Started byDemian Brecht <demianbrecht@gmail.com>
First post2012-11-04 22:27 -0800
Last post2012-11-05 01:55 -0800
Articles 20 on this page of 59 — 20 participants

Back to article view | Back to comp.lang.python


Contents

  Multi-dimensional list initialization Demian Brecht <demianbrecht@gmail.com> - 2012-11-04 22:27 -0800
    Re: Multi-dimensional list initialization Hans Mulder <hansmu@xs4all.nl> - 2012-11-05 10:13 +0100
      Re: Multi-dimensional list initialization Oscar Benjamin <oscar.j.benjamin@gmail.com> - 2012-11-06 01:32 +0000
      Re: Multi-dimensional list initialization Chris Angelico <rosuav@gmail.com> - 2012-11-06 13:01 +1100
      Re: Multi-dimensional list initialization Oscar Benjamin <oscar.j.benjamin@gmail.com> - 2012-11-06 02:30 +0000
      Re: Multi-dimensional list initialization Andrew Robinson <andrew3@r3dsolutions.com> - 2012-11-05 21:51 -0800
        Re: Multi-dimensional list initialization Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-11-06 09:04 +0000
          RE: Multi-dimensional list initialization "Shambhu Rajak" <shambhu.rajak@calsoftinc.com> - 2012-11-06 18:57 +0530
          Re: Multi-dimensional list initialization Andrew Robinson <andrew3@r3dsolutions.com> - 2012-11-06 14:41 -0800
            Re: Multi-dimensional list initialization Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-11-07 01:55 +0000
              Re: Multi-dimensional list initialization Demian Brecht <demianbrecht@gmail.com> - 2012-11-06 22:56 -0800
              Re: Multi-dimensional list initialization wxjmfauth@gmail.com - 2012-11-07 00:57 -0800
              Re: Multi-dimensional list initialization Mark Lawrence <breamoreboy@yahoo.co.uk> - 2012-11-07 22:27 +0000
              Re: Multi-dimensional list initialization Ian Kelly <ian.g.kelly@gmail.com> - 2012-11-07 16:39 -0700
              Re: Multi-dimensional list initialization Ian Kelly <ian.g.kelly@gmail.com> - 2012-11-08 00:09 -0700
              Re: Multi-dimensional list initialization Ian Kelly <ian.g.kelly@gmail.com> - 2012-11-08 08:58 -0700
              Re: Multi-dimensional list initialization Mark Lawrence <breamoreboy@yahoo.co.uk> - 2012-11-09 01:39 +0000
              Re: Multi-dimensional list initialization Chris Angelico <rosuav@gmail.com> - 2012-11-09 17:07 +1100
                Re: Multi-dimensional list initialization Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-11-09 06:37 +0000
                  Re: Multi-dimensional list initialization Chris Angelico <rosuav@gmail.com> - 2012-11-09 17:59 +1100
                  Re: Multi-dimensional list initialization Mark Lawrence <breamoreboy@yahoo.co.uk> - 2012-11-09 07:27 +0000
                  Re: Multi-dimensional list initialization rusi <rustompmody@gmail.com> - 2012-11-09 07:05 -0800
                    Re: Multi-dimensional list initialization Chris Angelico <rosuav@gmail.com> - 2012-11-10 02:23 +1100
              Re: Multi-dimensional list initialization Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2012-11-09 14:34 -0500
              RE: Multi-dimensional list initialization "Prasad, Ramit" <ramit.prasad@jpmorgan.com> - 2012-11-09 20:31 +0000
              Re: Multi-dimensional list initialization Ethan Furman <ethan@stoneleaf.us> - 2012-11-09 13:49 -0800
          RE: Multi-dimensional list initialization "Prasad, Ramit" <ramit.prasad@jpmorgan.com> - 2012-11-06 23:39 +0000
          Re: Multi-dimensional list initialization Ian Kelly <ian.g.kelly@gmail.com> - 2012-11-06 16:52 -0700
          Re: Multi-dimensional list initialization MRAB <python@mrabarnett.plus.com> - 2012-11-07 00:23 +0000
            Re: Multi-dimensional list initialization rusi <rustompmody@gmail.com> - 2012-11-06 20:11 -0800
            Re: Multi-dimensional list initialization Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-11-07 05:05 +0000
              Re: Multi-dimensional list initialization Roy Smith <roy@panix.com> - 2012-11-07 00:12 -0500
                Re: Multi-dimensional list initialization Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2012-11-07 18:32 +1300
                  RE: Multi-dimensional list initialization "Prasad, Ramit" <ramit.prasad@jpmorgan.com> - 2012-11-07 15:57 +0000
              Re: Multi-dimensional list initialization Jussi Piitulainen <jpiitula@ling.helsinki.fi> - 2012-11-07 10:52 +0200
              Re: Multi-dimensional list initialization MRAB <python@mrabarnett.plus.com> - 2012-11-07 17:17 +0000
                Re: Multi-dimensional list initialization Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-11-07 22:36 +0000
          Re: Multi-dimensional list initialization Ethan Furman <ethan@stoneleaf.us> - 2012-11-07 07:23 -0800
          Re: Multi-dimensional list initialization Ian Kelly <ian.g.kelly@gmail.com> - 2012-11-07 14:01 -0700
            Re: Multi-dimensional list initialization Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-11-08 00:00 +0000
              Re: Multi-dimensional list initialization Oscar Benjamin <oscar.j.benjamin@gmail.com> - 2012-11-08 00:30 +0000
                Re: Multi-dimensional list initialization Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-11-08 03:47 +0000
              Re: Multi-dimensional list initialization Andrew Robinson <andrew3@r3dsolutions.com> - 2012-11-07 20:51 -0800
              Re: Multi-dimensional list initialization wrw@mac.com - 2012-11-08 08:26 -0500
          Re: Multi-dimensional list initialization Andrew Robinson <andrew3@r3dsolutions.com> - 2012-11-07 16:24 -0800
            Re: Multi-dimensional list initialization Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-11-08 04:20 +0000
      Re: Multi-dimensional list initialization Chris Angelico <rosuav@gmail.com> - 2012-11-06 17:07 +1100
      Re: Multi-dimensional list initialization Andrew Robinson <andrew3@r3dsolutions.com> - 2012-11-06 00:21 -0800
      Re: Multi-dimensional list initialization Ian Kelly <ian.g.kelly@gmail.com> - 2012-11-06 02:19 -0700
      RE: Multi-dimensional list initialization "Prasad, Ramit" <ramit.prasad@jpmorgan.com> - 2012-11-06 17:32 +0000
      Re: Multi-dimensional list initialization Andrew Robinson <andrew3@r3dsolutions.com> - 2012-11-06 13:14 -0800
      Re: Multi-dimensional list initialization Andrew Robinson <andrew3@r3dsolutions.com> - 2012-11-06 13:19 -0800
      Re: Multi-dimensional list initialization Ian Kelly <ian.g.kelly@gmail.com> - 2012-11-06 15:46 -0700
        Re: Multi-dimensional list initialization Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2012-11-07 18:34 +1300
          Re: Multi-dimensional list initialization Oscar Benjamin <oscar.j.benjamin@gmail.com> - 2012-11-07 14:00 +0000
          Re: Multi-dimensional list initialization Ethan Furman <ethan@stoneleaf.us> - 2012-11-07 06:47 -0800
          Re: Multi-dimensional list initialization Oscar Benjamin <oscar.j.benjamin@gmail.com> - 2012-11-07 23:06 +0000
          Re: Multi-dimensional list initialization Greg Ewing <greg.ewing@canterbury.ac.nz> - 2012-11-08 14:29 +1300
    Re: Multi-dimensional list initialization wxjmfauth@gmail.com - 2012-11-05 01:55 -0800

Page 2 of 3 — ← Prev page 1 [2] 3  Next page →


#33000

FromMark Lawrence <breamoreboy@yahoo.co.uk>
Date2012-11-09 07:27 +0000
Message-ID<mailman.3479.1352446120.27098.python-list@python.org>
In reply to#32998
On 09/11/2012 06:37, Steven D'Aprano wrote:
> On Fri, 09 Nov 2012 17:07:09 +1100, Chris Angelico wrote:
>
>> On Fri, Nov 9, 2012 at 12:39 PM, Mark Lawrence <breamoreboy@yahoo.co.uk>
>> wrote:
>>> On 07/11/2012 01:55, Steven D'Aprano wrote:
>>>>
>>>>
>>>> Who knows? Who cares? Nobody does:
>>>>
>>>> n -= n
>>>>
>>>>
>>> But I've seen this scattered through code:
>>>
>>> x := x - x - x
>>
>> Can you enlighten us as to how this is better than either:
>>   x := -x
>> or
>>   x := 0 - x
>> ? I'm not seeing it.
>
> I'm hoping that Mark intended it as an example of crappy code he has
> spotted in some other language rather than a counter-example of something
> you would do.

Correct, CORAL 66 and pointed out to me by a colleague when another team 
member had resigned.

>
> To be pedantic... there may very well be some (rare) cases where you
> actually do want x -= x rather than just x = 0. Consider the case where x
> could be an INF or NAN. Then x -= x should give x = NAN rather than zero.
> That may be desirable in some cases.

Interesting what comes up when we get chatting here.  I hope we don't 
get punished for going off topic :)

>
> At the very least, the compiler should NOT optimize away x = x - x to
> x = 0 if x could be a float, complex or Decimal.
>

X was an int so almost certainly optimised away by the SDL compiler on 
VMS of 1986 or 1987.

-- 
Cheers.

Mark Lawrence.

[toc] | [prev] | [next] | [standalone]


#33029

Fromrusi <rustompmody@gmail.com>
Date2012-11-09 07:05 -0800
Message-ID<ef8a7756-73fb-4693-97fb-24778360a91c@vy11g2000pbb.googlegroups.com>
In reply to#32998
On Nov 9, 11:37 am, Steven D'Aprano <steve
+comp.lang.pyt...@pearwood.info> wrote:
> On Fri, 09 Nov 2012 17:07:09 +1100, Chris Angelico wrote:
> > On Fri, Nov 9, 2012 at 12:39 PM, Mark Lawrence <breamore...@yahoo.co.uk>
> > wrote:
> >> On 07/11/2012 01:55, Steven D'Aprano wrote:
>
> >>> Who knows? Who cares? Nobody does:
>
> >>> n -= n
>
> >> But I've seen this scattered through code:
>
> >> x := x - x - x
>
> > Can you enlighten us as to how this is better than either:
> >  x := -x
> > or
> >  x := 0 - x
> > ? I'm not seeing it.
>
> I'm hoping that Mark intended it as an example of crappy code he has
> spotted in some other language rather than a counter-example of something
> you would do.
>
> To be pedantic... there may very well be some (rare) cases where you
> actually do want x -= x rather than just x = 0. Consider the case where x
> could be an INF or NAN. Then x -= x should give x = NAN rather than zero.
> That may be desirable in some cases.

In x86 assembler
mov ax, 0
is 4 bytes
sub ax, ax
is 2
and therefore better (at least for those brought up on Peter Norton);
the most common being
xor ax, ax

[toc] | [prev] | [next] | [standalone]


#33030

FromChris Angelico <rosuav@gmail.com>
Date2012-11-10 02:23 +1100
Message-ID<mailman.3498.1352474618.27098.python-list@python.org>
In reply to#33029
On Sat, Nov 10, 2012 at 2:05 AM, rusi <rustompmody@gmail.com> wrote:
> In x86 assembler
> mov ax, 0
> is 4 bytes

Three bytes actually, B8 00 00 if my memory hasn't failed me. BA for
DX, B9 ought to be BX and BB CX, I think. But yes, the xor or sub is
two bytes and one clock.

ChrisA

[toc] | [prev] | [next] | [standalone]


#33046

FromDennis Lee Bieber <wlfraed@ix.netcom.com>
Date2012-11-09 14:34 -0500
Message-ID<mailman.3511.1352489673.27098.python-list@python.org>
In reply to#32860
On Fri, 9 Nov 2012 17:07:09 +1100, Chris Angelico <rosuav@gmail.com>
declaimed the following in gmane.comp.python.general:

> On Fri, Nov 9, 2012 at 12:39 PM, Mark Lawrence <breamoreboy@yahoo.co.uk> wrote:
> > On 07/11/2012 01:55, Steven D'Aprano wrote:
> >>
> >>
> >> Who knows? Who cares? Nobody does:
> >>
> >> n -= n
> >>
> >
> > But I've seen this scattered through code:
> >
> > x := x - x - x
> 
> Can you enlighten us as to how this is better than either:
>  x := -x
> or
>  x := 0 - x

	Of course, if one has a language that, for some reason, evaluates
right-to-left (APL, anyone), then

	x := x - x - x

becomes

	x := x - 0

<G>

-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
        wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

[toc] | [prev] | [next] | [standalone]


#33047

From"Prasad, Ramit" <ramit.prasad@jpmorgan.com>
Date2012-11-09 20:31 +0000
Message-ID<mailman.3512.1352493345.27098.python-list@python.org>
In reply to#32860
Dennis Lee Bieber wrote:
> 
> On Fri, 9 Nov 2012 17:07:09 +1100, Chris Angelico <rosuav@gmail.com>
> declaimed the following in gmane.comp.python.general:
> 
> > On Fri, Nov 9, 2012 at 12:39 PM, Mark Lawrence <breamoreboy@yahoo.co.uk> wrote:
> > > On 07/11/2012 01:55, Steven D'Aprano wrote:
> > >>
> > >>
> > >> Who knows? Who cares? Nobody does:
> > >>
> > >> n -= n
> > >>
> > >
> > > But I've seen this scattered through code:
> > >
> > > x := x - x - x
> >
> > Can you enlighten us as to how this is better than either:
> >  x := -x
> > or
> >  x := 0 - x
> 
> 	Of course, if one has a language that, for some reason, evaluates
> right-to-left (APL, anyone), then
> 
> 	x := x - x - x
> 
> becomes
> 
> 	x := x - 0
> 

Is that not the same as x:=-x?


~Ramit


This email is confidential and subject to important disclaimers and
conditions including on offers for the purchase or sale of
securities, accuracy and completeness of information, viruses,
confidentiality, legal privilege, and legal entity disclaimers,
available at http://www.jpmorgan.com/pages/disclosures/email.  

[toc] | [prev] | [next] | [standalone]


#33058

FromEthan Furman <ethan@stoneleaf.us>
Date2012-11-09 13:49 -0800
Message-ID<mailman.3520.1352498168.27098.python-list@python.org>
In reply to#32860
Prasad, Ramit wrote:
> Dennis Lee Bieber wrote:
>> 	Of course, if one has a language that, for some reason, evaluates
>> right-to-left (APL, anyone), then
>>
>> 	x := x - x - x
>>
>> becomes
>>
>> 	x := x - 0
> 
> Is that not the same as x:=-x?

No, its the same as 'x = x'.

~Ethan~

[toc] | [prev] | [next] | [standalone]


#32853

From"Prasad, Ramit" <ramit.prasad@jpmorgan.com>
Date2012-11-06 23:39 +0000
Message-ID<mailman.3346.1352245174.27098.python-list@python.org>
In reply to#32811
Andrew Robinson wrote:
> 
> On 11/06/2012 01:04 AM, Steven D'Aprano wrote:
> > On Mon, 05 Nov 2012 21:51:24 -0800, Andrew Robinson wrote:
> >
[snip]
> >      Q: What about other mutable objects like sets or dicts?
> >      A: No, the elements are never copied.
> They aren't list multiplication compatible in any event! It's a total
> nonsense objection.
> 
> If these are inconsistent in my idea -- OBVIOUSLY -- they are
> inconsistent in Python's present implementation.  You can't even
> reference duplicate them NOW.
> 
>  >>> { 1:'a', 2:'b', 3:'c' } * 2
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
> TypeError: unsupported operand type(s) for *: 'dict' and 'int'

>>> z = [ {'a':1} ]*10
>>> z[0]['b'] = 4
>>> z
[{'a': 1, 'b': 4}, {'a': 1, 'b': 4}, {'a': 1, 'b': 4},{'a': 1, 'b': 4}, 
{'a': 1, 'b': 4}, {'a': 1, 'b': 4}, {'a': 1, 'b': 4}, {'a': 1, 'b': 4},
{'a': 1, 'b': 4}, {'a': 1, 'b': 4}]

Should that copy the dictionary? According to logical reasoning
it should copy the dictionary as well. How do you draw the line of 
what should be copied and what should not? 

> 
> >      Q: How about on Tuesdays? I bet they're copied on Tuesdays.
> >      A: No, the elements are never copied.
> That's really a stupid objection, and everyone knows it.

Agreed. [snip]

> >      Q: How about if I use delegation to proxy a list?
> >      A: Oh no, they definitely won't be copied.
> Give an example usage of why someone would want to do this.  Then we can
> discuss it.

IIRC, someone wanted to do something very similar for dictionaries to 
prevent editing of global variables.

> >      Q: What about other mutable objects like sets or dicts?
> >      A: No, definitely not. Unless people complain enough.
> now you're just repeating yourself to make your contrived list longer --
> but there's no new objections...

This is my main objection and one of the flaws of your argument.
You want to handle one type of mutable objects completely separately
than other mutable objects. Why is list any different than dictionary
in this respect? The only reason I can imagine is because lists
end up being used for 2d (or higher) "matrices".

> 
> > Losing consistency in favour of saving a few characters for something as
> > uncommon as list multiplication is a poor tradeoff. That's why this
> > proposal has been rejected again and again and again every time it has
> > been suggested.
> Please link to the objection being proposed to the developers, and their
> reasoning for rejecting it.
> I think you are exaggerating.

I reject (as a developer) it because it forces me to remember a very 
specific quirk versus a simple (logical) rule that applies to all objects. Not to mention that the quirk is not even that useful except for beginners.

> 
> > List multiplication [x]*n is conceptually equivalent to:
> > <snip>
> > This is nice and simple and efficient.
> No it isn't efficient. It's *slow* when done as in your example.
> 
> > Copying other objects is slow and inefficient. Keeping list
> > multiplication consistent, and fast, is MUCH more important than making
> > it work as expected for the rare case of 2D arrays:
> I don't think so -- again, look at range(); it was made to work
> inconsistent for a "common" case.
> 
> Besides, 2D arrays are *not* rare and people *have* to copy internals of
> them very often.
> The copy speed will be the same or *faster*, and the typing less -- and
> the psychological mistakes *less*, the elegance more.
> 
> It's hardly going to confuse anyone to say that lists are copied with
> list multiplication, but the elements are not.
> 
> Every time someone passes a list to a function, they *know* that the
> list is passed by value -- and the elements are passed by reference.
> People in Python are USED to lists being "the" way to weird behavior
> that other languages don't do.

I think you just lost 90% of your credibility (with me). When did lists 
get passed by value? Python uses call by sharing[0]. 

Terminology aside, lists are handled exactly the same way as all
other objects; the rules regarding their mutability in the callee
are the same as dictionaries, sets, or any mutable type (including
non-builtins). 
  

> 
> >
> > Copying those elements does not come for free.
> >
> > It is true that list multiplication can be much faster than a list comp.
> > But that's because the list multiply doesn't have to inspect the
> > elements, copy them, or engage the iteration machinery. Avoiding copying
> > gives you a big saving:
> >
> >
> > [steve@ando ~]$ python3.3 -m timeit -s "x = range(1000)"
> > "[x for _ in range(100)]"  # not copied
> > 100000 loops, best of 3: 11.9 usec per loop
> >
> > [steve@ando utilities]$ python3.3 -m timeit -s "x = range(1000)"
> > "[x[:] for _ in range(100)]"  # copied
> > 10000 loops, best of 3: 103 usec per loop
> >
> > So there's a factor of ten difference right there. If list multiplication
> > had to make copies, it would lose much of its speed advantage.
> And when multiplication doesn't make copies of *lists*, it's going
> "nowhere fast", because people don't want the results that gives.
> 
> So what difference does it make?  People won't make the construction
> unless they wanted to make the copies in the first place.  If they want
> the copies, well -- copies are *slow*.  Big deal.
> 
> >   For large
> > enough lists, or complicated enough objects, it would become slower than
> > a list comprehension.
> Huh? You're nuts.
> 
> > It would be even slower if list multiplication had to inspect each
> > element first and decide whether or not to copy.
> A single pointer comparison in a 'C' for loop takes less than 5 nano
> seconds on a 1Ghz machine.
> (I'll bet yours is faster than that...!)
> Consider: list objects have a pointer which points back to the generic
> list object -- that's all it takes to determine what the "type" is.
> 
> Your measured loop times, doing list comprehensions takes over 10
> microseconds *per loop*.
> Compared to what you're proposing -- The pointer compare is a mere 0.05%
> change;  You can't even measure that with "timeit!".  BUT: The increase
> in speed for not running tokenized "for" loops is *much* bigger than the
> loss for a single pointer compare; so it will *usually* be a *serious*
> net gain.
> 
> >> I really don't think doing a shallow copy of lists would break anyone's
> >> program.
> > Anyone who is currently using list multiplication with mutable objects is
> > expecting that they will be the same object, and relying on that fact.
> > Otherwise they wouldn't be using list multiplication.
> yes, and I'm not changing that -- except for lists; and *no* one is
> using that.
> Find two examples of it from existing non contrived web examples of
> Python code.
> *ask* around.

I am positive that majority of code is not examples--web or otherwise.

> 
> >
> > You're suggesting a semantic change. Therefore they will be expecting
> > something different from what actually happens. Result: broken code.
> Even if it was;  So are many semantic changes happening between python 2
> and python 3.
> Look at what python 2 did:
> 
>  >>> range(0,5)[0]
> 0
>  >>> range(0,5)[1:3]
> [1, 2]
> 
> That's a *semantic* change.
> Also; if you complain that xrange has been renamed range; then look:
> 
>  >>> xrange(0,5)[0]
> 0
>  >>> xrange(0,5)[1:3]
> Traceback (most recent call last):
>    File "<stdin>", line 1, in <module>
> TypeError: sequence index must be integer, not 'slice'
> 
> WOW. WOW. WOW.  An even BIGGER semantic change.

So because one thing has a semantic change that gives license
for semantic changes everywhere? Bah, ridiculous!

[snip]
> 
> > to get the behaviour you want, and then in Python 3.5 it would become the
> > default. That's three years until it becomes the standard. Meanwhile,
> > there will still be millions of people using Python 2.7 or 3.2, and their
> > code will behave differently from your code.
> Uh, they aren't *using* the construction I am proposing now -- they are
> avoiding it like the plague.
> Hence, it will merely become a new ability in a few years -- not
> 'differently' behaving code.

How in the name of <insert deity (or religion)> do you have any clue 
about that? Granted, as an educated you *may* be right, but you
may not be. I have no idea how you could know this definitively
or with any great degree of certainty. [snip]


~Ramit

[0] http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing


This email is confidential and subject to important disclaimers and
conditions including on offers for the purchase or sale of
securities, accuracy and completeness of information, viruses,
confidentiality, legal privilege, and legal entity disclaimers,
available at http://www.jpmorgan.com/pages/disclosures/email.  

[toc] | [prev] | [next] | [standalone]


#32854

FromIan Kelly <ian.g.kelly@gmail.com>
Date2012-11-06 16:52 -0700
Message-ID<mailman.3347.1352245953.27098.python-list@python.org>
In reply to#32811
On Tue, Nov 6, 2012 at 3:41 PM, Andrew Robinson
<andrew3@r3dsolutions.com> wrote:
>>      Q: What about other mutable objects like sets or dicts?
>>      A: No, the elements are never copied.
>
> They aren't list multiplication compatible in any event! It's a total
> nonsense objection.
>
> If these are inconsistent in my idea -- OBVIOUSLY -- they are inconsistent
> in Python's present implementation.  You can't even reference duplicate them
> NOW.
>
>>>> { 1:'a', 2:'b', 3:'c' } * 2
>
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> TypeError: unsupported operand type(s) for *: 'dict' and 'int'

The objection is not nonsense; you've merely misconstrued it.  If
[[1,2,3]] * 4 is expected to create a mutable matrix of 1s, 2s, and
3s, then one would expect [[{}]] * 4 to create a mutable matrix of
dicts.  If the dicts are not copied, then this fails for the same
reason

>>      Q: How about if I use delegation to proxy a list?
>>      A: Oh no, they definitely won't be copied.
>
> Give an example usage of why someone would want to do this.  Then we can
> discuss it.

Seriously?  Read a book on design patterns.  You might start at SO:

http://stackoverflow.com/questions/832536/when-to-use-delegation-instead-of-inheritance

>> Losing consistency in favour of saving a few characters for something as
>> uncommon as list multiplication is a poor tradeoff. That's why this
>> proposal has been rejected again and again and again every time it has
>> been suggested.
>
> Please link to the objection being proposed to the developers, and their
> reasoning for rejecting it.
> I think you are exaggerating.

>From Google:

http://bugs.python.org/issue1408
http://bugs.python.org/issue12597
http://bugs.python.org/issue9108
http://bugs.python.org/issue7823

Note that in two out of these four cases, the reporter was trying to
multiply lists of dicts, not just lists of lists.

> Besides, 2D arrays are *not* rare and people *have* to copy internals of
> them very often.
> The copy speed will be the same or *faster*, and the typing less -- and the
> psychological mistakes *less*, the elegance more.

List multiplication is not potentially useful for copying 2D lists,
only for initializing them.  For copying an existing nested list,
you're still stuck with either copy.deepcopy() or a list
comprehension.

> It's hardly going to confuse anyone to say that lists are copied with list
> multiplication, but the elements are not.
>
> Every time someone passes a list to a function, they *know* that the list is
> passed by value -- and the elements are passed by reference.  People in
> Python are USED to lists being "the" way to weird behavior that other
> languages don't do.

Incorrect.  Python uses what is commonly known as call-by-object, not
call-by-value or call-by-reference.  Passing the list by value would
imply that the list is copied, and that appends or removes to the list
inside the function would not affect the original list.  This is not
what Python does; the list inside the function and the list passed in
are the same list.  At the same time, the function does not have
access to the original reference to the list and cannot reassign it by
reassigning its own reference, so it is not call-by-reference
semantics either.

[toc] | [prev] | [next] | [standalone]


#32857

FromMRAB <python@mrabarnett.plus.com>
Date2012-11-07 00:23 +0000
Message-ID<mailman.3349.1352248012.27098.python-list@python.org>
In reply to#32811
On 2012-11-06 23:52, Ian Kelly wrote:
> On Tue, Nov 6, 2012 at 3:41 PM, Andrew Robinson
> <andrew3@r3dsolutions.com> wrote:
>>>      Q: What about other mutable objects like sets or dicts?
>>>      A: No, the elements are never copied.
>>
>> They aren't list multiplication compatible in any event! It's a total
>> nonsense objection.
>>
>> If these are inconsistent in my idea -- OBVIOUSLY -- they are inconsistent
>> in Python's present implementation.  You can't even reference duplicate them
>> NOW.
>>
>>>>> { 1:'a', 2:'b', 3:'c' } * 2
>>
>> Traceback (most recent call last):
>>   File "<stdin>", line 1, in <module>
>> TypeError: unsupported operand type(s) for *: 'dict' and 'int'
>
> The objection is not nonsense; you've merely misconstrued it.  If
> [[1,2,3]] * 4 is expected to create a mutable matrix of 1s, 2s, and
> 3s, then one would expect [[{}]] * 4 to create a mutable matrix of
> dicts.  If the dicts are not copied, then this fails for the same
> reason
>
>>>      Q: How about if I use delegation to proxy a list?
>>>      A: Oh no, they definitely won't be copied.
>>
>> Give an example usage of why someone would want to do this.  Then we can
>> discuss it.
>
> Seriously?  Read a book on design patterns.  You might start at SO:
>
> http://stackoverflow.com/questions/832536/when-to-use-delegation-instead-of-inheritance
>
>>> Losing consistency in favour of saving a few characters for something as
>>> uncommon as list multiplication is a poor tradeoff. That's why this
>>> proposal has been rejected again and again and again every time it has
>>> been suggested.
>>
>> Please link to the objection being proposed to the developers, and their
>> reasoning for rejecting it.
>> I think you are exaggerating.
>
>>From Google:
>
> http://bugs.python.org/issue1408
> http://bugs.python.org/issue12597
> http://bugs.python.org/issue9108
> http://bugs.python.org/issue7823
>
> Note that in two out of these four cases, the reporter was trying to
> multiply lists of dicts, not just lists of lists.
>
>> Besides, 2D arrays are *not* rare and people *have* to copy internals of
>> them very often.
>> The copy speed will be the same or *faster*, and the typing less -- and the
>> psychological mistakes *less*, the elegance more.
>
> List multiplication is not potentially useful for copying 2D lists,
> only for initializing them.  For copying an existing nested list,
> you're still stuck with either copy.deepcopy() or a list
> comprehension.
>
>> It's hardly going to confuse anyone to say that lists are copied with list
>> multiplication, but the elements are not.
>>
>> Every time someone passes a list to a function, they *know* that the list is
>> passed by value -- and the elements are passed by reference.  People in
>> Python are USED to lists being "the" way to weird behavior that other
>> languages don't do.
>
> Incorrect.  Python uses what is commonly known as call-by-object, not
> call-by-value or call-by-reference.  Passing the list by value would
> imply that the list is copied, and that appends or removes to the list
> inside the function would not affect the original list.  This is not
> what Python does; the list inside the function and the list passed in
> are the same list.  At the same time, the function does not have
> access to the original reference to the list and cannot reassign it by
> reassigning its own reference, so it is not call-by-reference
> semantics either.
>
I prefer the term "reference semantics".

[toc] | [prev] | [next] | [standalone]


#32864

Fromrusi <rustompmody@gmail.com>
Date2012-11-06 20:11 -0800
Message-ID<83e321db-65e1-424f-9166-5261caa12be5@px4g2000pbc.googlegroups.com>
In reply to#32857
On Nov 7, 5:26 am, MRAB <pyt...@mrabarnett.plus.com> wrote:
> I prefer the term "reference semantics".

Ha! That hits the nail on the head.

To go back to the OP:

On Nov 5, 11:28 am, Demian Brecht <demianbre...@gmail.com> wrote:
> So, here I was thinking "oh, this is a nice, easy way to initialize a 4D matrix" (running 2.7.3, non-core libs not allowed):
>
> m = [[None] * 4] * 4
>
> The way to get what I was after was:
>
> m = [[None] * 4, [None] * 4, [None] * 4, [None * 4]]
>
> (Obviously, I could have just hardcoded the initialization, but I'm too lazy to type all that out ;))
>
> The behaviour I encountered seems a little contradictory to me. [None] * 4 creates four distinct elements in a single array while [[None] * 4] * 4 creates one distinct array of four distinct elements, with three references to it:
>
> >>> a = [None] * 4
> >>> a[0] = 'a'
> >>> a
>
> ['a', None, None, None]
>
> >>> m = [[None] * 4] * 4
> >>> m[0][0] = 'm'
> >>> m
>
> [['m', None, None, None], ['m', None, None, None], ['m', None, None, None], ['m', None, None, None]]
>
> Is this expected behaviour and if so, why? In my mind either result makes sense, but the inconsistency is what throws me off.
>

m=[[None] * 2] * 3

is the same as

m=[[None]*2, [None]*2, [None]*2]

until one starts doing things like

m[0][0] = 'm'

So dont do it!

And to get python to help you by saying the same that I am saying do
m=((None) * 2) * 3
(well almost... its a bit more messy in practice)
m=(((None,) * 2),)*3

After that try assigning to m[0][0] and python will kindly say NO!

tl;dr version:
reference semantics is ok
assignment is ok (well up to a point)
assignment + reference semantics is not

[toc] | [prev] | [next] | [standalone]


#32867

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2012-11-07 05:05 +0000
Message-ID<5099ec1d$0$21759$c3e8da3$76491128@news.astraweb.com>
In reply to#32857
On Wed, 07 Nov 2012 00:23:44 +0000, MRAB wrote:

>> Incorrect.  Python uses what is commonly known as call-by-object, not
>> call-by-value or call-by-reference.  Passing the list by value would
>> imply that the list is copied, and that appends or removes to the list
>> inside the function would not affect the original list.  This is not
>> what Python does; the list inside the function and the list passed in
>> are the same list.  At the same time, the function does not have access
>> to the original reference to the list and cannot reassign it by
>> reassigning its own reference, so it is not call-by-reference semantics
>> either.
>>
> I prefer the term "reference semantics".


Oh good, because what the world needs is yet another name for the same 
behaviour.

- call by sharing
- call by object sharing
- call by object reference
- call by object
- call by value, where "values" are references 
  (according to the Java community)
- call by reference, where "references" refer to objects, not variables
  (according to the Ruby community)
- reference semantics


Anything else?

http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing




-- 
Steven

[toc] | [prev] | [next] | [standalone]


#32868

FromRoy Smith <roy@panix.com>
Date2012-11-07 00:12 -0500
Message-ID<roy-08B0E5.00121807112012@news.panix.com>
In reply to#32867
In article <5099ec1d$0$21759$c3e8da3$76491128@news.astraweb.com>,
 Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote:

> On Wed, 07 Nov 2012 00:23:44 +0000, MRAB wrote:
> 
> >> Incorrect.  Python uses what is commonly known as call-by-object, not
> >> call-by-value or call-by-reference.  Passing the list by value would
> >> imply that the list is copied, and that appends or removes to the list
> >> inside the function would not affect the original list.  This is not
> >> what Python does; the list inside the function and the list passed in
> >> are the same list.  At the same time, the function does not have access
> >> to the original reference to the list and cannot reassign it by
> >> reassigning its own reference, so it is not call-by-reference semantics
> >> either.
> >>
> > I prefer the term "reference semantics".
> 
> 
> Oh good, because what the world needs is yet another name for the same 
> behaviour.
> 
> - call by sharing
> - call by object sharing
> - call by object reference
> - call by object
> - call by value, where "values" are references 
>   (according to the Java community)
> - call by reference, where "references" refer to objects, not variables
>   (according to the Ruby community)
> - reference semantics
> 
> 
> Anything else?
> 
> http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing

Call by social network?  The called function likes the object.  
Depending on how it feels, it can also comment on some of the object's 
attributes.

[toc] | [prev] | [next] | [standalone]


#32869

FromGregory Ewing <greg.ewing@canterbury.ac.nz>
Date2012-11-07 18:32 +1300
Message-ID<afua2iFbj9gU1@mid.individual.net>
In reply to#32868
Roy Smith wrote:
> Call by social network?  The called function likes the object.  
> Depending on how it feels, it can also comment on some of the object's 
> attributes.

And then finds that it has inadvertently shared all its
private data with other functions accessing the object.

-- 
Greg

[toc] | [prev] | [next] | [standalone]


#32890

From"Prasad, Ramit" <ramit.prasad@jpmorgan.com>
Date2012-11-07 15:57 +0000
Message-ID<mailman.3374.1352303916.27098.python-list@python.org>
In reply to#32869
Gregory Ewing wrote:
> 
> Roy Smith wrote:
> > Call by social network?  The called function likes the object.
> > Depending on how it feels, it can also comment on some of the object's
> > attributes.
> 
> And then finds that it has inadvertently shared all its
> private data with other functions accessing the object.

And this is where Dihedral 8888 (or whatever the bot is called)
tells you that Python has no "private" variables. :)


~Ramit


This email is confidential and subject to important disclaimers and
conditions including on offers for the purchase or sale of
securities, accuracy and completeness of information, viruses,
confidentiality, legal privilege, and legal entity disclaimers,
available at http://www.jpmorgan.com/pages/disclosures/email.  

[toc] | [prev] | [next] | [standalone]


#32879

FromJussi Piitulainen <jpiitula@ling.helsinki.fi>
Date2012-11-07 10:52 +0200
Message-ID<qot625hyeu6.fsf@ruuvi.it.helsinki.fi>
In reply to#32867
Steven D'Aprano writes:
> On Wed, 07 Nov 2012 00:23:44 +0000, MRAB wrote:

> > I prefer the term "reference semantics".
> 
> Oh good, because what the world needs is yet another name for the
> same behaviour.
> 
> - call by sharing
> - call by object sharing
> - call by object reference
> - call by object
> - call by value, where "values" are references 
>   (according to the Java community)
> - call by reference, where "references" refer to objects, not variables
>   (according to the Ruby community)
> - reference semantics
> 
> Anything else?
> 
> http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing

Something else:

There's a call-by-* versus pass-by-* distinction, where the call-by-*
would be rather different from any of the above:

- call-by-value is what most languages now use: argument expressions
  are reduced to values before they are passed to the function /
  procedure / method / whatever.

- call-by-name was something Algol 60 had by default: something like
  evaluating the argument expression every time its value is needed

- call-by-need: argument expression is reduced to a value the first
  time its value is needed (if ever)

- call-by-lazy (increasingly silly terminology, and I don't quite have
  an idea what it means in contrast to call-by-need)

The modern confusions would then be mostly over the pass-by-* family,
invariably using call-by-value in the above sense. The terminology for
these tends to produce more heat than light, but I think the relevant
distinctions are mostly just these:

- can one modify the argument effectively [Python: yes]

- can one modify the parameter with abandon [Python: don't]

- can one swap [Python: no]

- possibly: is it expensive to pass large objects? [Python: no]

The actual rule in Scheme, Java, and Python is the same simple and
sane rule: what are passed are values (argument expressions are fully
evaluated before the actual call takes place), parameter passing does
not involve any (observable) copying, and the arguments are bound to
fresh variables (no aliasing of variables).

Different communities use different words. Sometimes they use the same
words about different things. Resulting in more heat than light :(

(I'd have a few more things in the something-else department, but this
is already much longer than I thought. Ends.)

[toc] | [prev] | [next] | [standalone]


#32898

FromMRAB <python@mrabarnett.plus.com>
Date2012-11-07 17:17 +0000
Message-ID<mailman.3383.1352308622.27098.python-list@python.org>
In reply to#32867
On 2012-11-07 05:05, Steven D'Aprano wrote:
> On Wed, 07 Nov 2012 00:23:44 +0000, MRAB wrote:
>
>>> Incorrect.  Python uses what is commonly known as call-by-object, not
>>> call-by-value or call-by-reference.  Passing the list by value would
>>> imply that the list is copied, and that appends or removes to the list
>>> inside the function would not affect the original list.  This is not
>>> what Python does; the list inside the function and the list passed in
>>> are the same list.  At the same time, the function does not have access
>>> to the original reference to the list and cannot reassign it by
>>> reassigning its own reference, so it is not call-by-reference semantics
>>> either.
>>>
>> I prefer the term "reference semantics".
>
>
> Oh good, because what the world needs is yet another name for the same
> behaviour.
>
> - call by sharing
> - call by object sharing
> - call by object reference
> - call by object
> - call by value, where "values" are references
>    (according to the Java community)
> - call by reference, where "references" refer to objects, not variables
>    (according to the Ruby community)
> - reference semantics
>
>
> Anything else?
>
> http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing
>
The disadvantage of calling it "call by ..." is that it suggests that
you're just talking about calling functions.

What about binding in general, eg "x = y"? Does it make sense to still
call it "call by ..."?

[toc] | [prev] | [next] | [standalone]


#32910

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2012-11-07 22:36 +0000
Message-ID<509ae285$0$29980$c3e8da3$5496439d@news.astraweb.com>
In reply to#32898
On Wed, 07 Nov 2012 17:17:02 +0000, MRAB wrote:

> The disadvantage of calling it "call by ..." is that it suggests that
> you're just talking about calling functions.

*shrug*

There are already two synonyms for this, "call by ..." and "pass by ...". 
They are old, venerable terms dating back to Algol and possibly even 
older. All the way back to Fortran perhaps?


> What about binding in general, eg "x = y"? Does it make sense to still
> call it "call by ..."?

Sure, why not? The person who prepares beef tartare or sushimi is still 
called the cook.


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#32888

FromEthan Furman <ethan@stoneleaf.us>
Date2012-11-07 07:23 -0800
Message-ID<mailman.3372.1352302286.27098.python-list@python.org>
In reply to#32811
After this post the only credibility you have left (with me, anyway) is that you seem to be willing 
to learn.  So learn the way Python works before you try to reimplement it.

~Ethan~

[toc] | [prev] | [next] | [standalone]


#32906

FromIan Kelly <ian.g.kelly@gmail.com>
Date2012-11-07 14:01 -0700
Message-ID<mailman.3390.1352322111.27098.python-list@python.org>
In reply to#32811
On Wed, Nov 7, 2012 at 12:51 PM, Andrew Robinson
<andrew3@r3dsolutions.com> wrote:
> Interesting, you avoided the main point "lists are copied with list
> multiplication".

It seems that each post is longer than the last.  If we each responded
to every point made, this thread would fill a book.

Anyway, your point was to suggest that people would not be confused by
having list multiplication copy lists but not other objects, because
passing lists into functions as parameters works in basically the same
way.  Except that it does not work the same way, because when lists
are passed into functions, they are not copied at all.  Nor are are
any of their contents copied, lists or not.  So actually I did address
this point with the "call-by-object" tangent; I just did not
explicitly link it back to your thesis.

> But, in any event:
> Pass by value (not call by value) is a term stretching back 30 years; eg:
> when I learned the meaning of the words.  Rewording it as "Call by value" is
> something that happened later, and the nuance is lost on those without a
> very wide programming knowledge *and* age.

Potayto, potahto.  The distinction that you're describing is between
"strict" versus "non-strict" evaluation strategies.  Hinging the
distinction on the non-descriptive words "call" and "pass" is lazy
terminology that should never have been introduced in the first place.

> In any event:
> All objects in Python are based on pointers; all parameters passed to
> functions, etc, are *copies* of those pointers; (by pointer value).

No, all parameters passed to functions are *objects*.  Python itself
has no concept of pointers.  What you describe is true as an
implementation detail for CPython but not necessarily true for other
implementations, and not true at all for an abstract
(implementation-independent) view of the language.

> I made the distinction between contents of the list and the list object
> itself for that reason; I gave an explicit correction to the pass by "value"
> generalization by saying: ("the elements are passed by reference").

The elements are not passed anywhere.  Only the list object is passed
to the function, which is completely agnostic of the fact that the
list object happens to contain other objects.

[toc] | [prev] | [next] | [standalone]


#32923

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2012-11-08 00:00 +0000
Message-ID<509af632$0$29980$c3e8da3$5496439d@news.astraweb.com>
In reply to#32906
Andrew, it appears that your posts are being eaten or rejected by my 
ISP's news server, because they aren't showing up for me. Possibly a side-
effect of your dates being in the distant past? So if you have replied to 
any of my posts, I haven't seen them.

In any case, I wanted to ask a question:


On Wed, 07 Nov 2012 14:01:19 -0700, Ian Kelly wrote:
> On Wed, Nov 7, 2012 at 12:51 PM, Andrew Robinson
> <andrew3@r3dsolutions.com> wrote:

[...]

>> But, in any event:
>> Pass by value (not call by value) is a term stretching back 30 years;
>> eg: when I learned the meaning of the words.  Rewording it as "Call by
>> value" is something that happened later, and the nuance is lost on
>> those without a very wide programming knowledge *and* age.

Every now and again I come across somebody who tries to distinguish 
between "call by foo" and "pass by foo", but nobody has been able to 
explain the difference (if any) to me. When you CALL a function, you PASS 
values to it. Hence the two terms are effectively synonyms, and both 
refer to the evaluation strategy when binding arguments to parameters.

If you believe that is incorrect, can you point me to something 
explaining the difference?



-- 
Steven

[toc] | [prev] | [next] | [standalone]


Page 2 of 3 — ← Prev page 1 [2] 3  Next page →

Back to top | Article view | comp.lang.python


csiph-web