Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #32748 > unrolled thread
| Started by | Demian Brecht <demianbrecht@gmail.com> |
|---|---|
| First post | 2012-11-04 22:27 -0800 |
| Last post | 2012-11-05 01:55 -0800 |
| Articles | 19 on this page of 59 — 20 participants |
Back to article view | Back to comp.lang.python
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 3 of 3 — ← Prev page 1 2 [3]
| From | Oscar Benjamin <oscar.j.benjamin@gmail.com> |
|---|---|
| Date | 2012-11-08 00:30 +0000 |
| Message-ID | <mailman.3414.1352334655.27098.python-list@python.org> |
| In reply to | #32923 |
On 8 November 2012 00:00, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote: > 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? Did you also miss MRAB's post above? It made sense to me. MRAB wrote: > 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]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2012-11-08 03:47 +0000 |
| Message-ID | <509b2b5c$0$29885$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #32926 |
On Thu, 08 Nov 2012 00:30:53 +0000, Oscar Benjamin wrote: >> 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? > > Did you also miss MRAB's post above? It made sense to me. You mean MRABs post which I replied to? Yes, I must have missed it :-P But seriously, no I didn't miss it. He doesn't give any evidence that there is a difference between "call by ..." and "pass by ..." when talking about binding arguments to formal parameters. His objection to "call by ..." is that it doesn't make it clear that the evaluation rules apply to simple binding/assignment as well as calling functions. -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Andrew Robinson <andrew3@r3dsolutions.com> |
|---|---|
| Date | 2012-11-07 20:51 -0800 |
| Message-ID | <mailman.3419.1352350234.27098.python-list@python.org> |
| In reply to | #32923 |
On 11/07/2012 04:00 PM, Steven D'Aprano wrote: > 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? Date has been corrected since two days ago. It will remain until a reboot.... Ignorance, though, might be bliss... > 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. I think the "Call by foo" came into vogue around the time of C++; Eg: It's in books like C++ for C programmers; I never saw it used before then so I *really* don't know for sure... I know "Pass by value" existed all the way back to the 1960's. I see "pass by" in my professional books from those times and even most newer ones; but I only find "Call by value" in popular programming books of more recent times. (Just my experience) So -- I "guess" the reason is that when invoking a subroutine, early hardware often had an assembler mnemonic by the name "call". See for example: Intelx86 hardware books from the 1970's; Most early processors (like the MC6809E, and 8080) allow both direct and indirect *references* to a function (C would call them function pointers); So, occasionally early assembly programs comment things like: "; dynamic VESA libraries are called by value in register D."; And they meant that register D is storing a function call address from two or more vesa cards. It had little to do with the function's parameters, (which might be globals anyway) (It procedural dynamic binding!) Today, I don't know for sure -- so I just don't use it. "pass" indicates a parameter of the present call; but not the present call itself.
[toc] | [prev] | [next] | [standalone]
| From | wrw@mac.com |
|---|---|
| Date | 2012-11-08 08:26 -0500 |
| Message-ID | <mailman.3438.1352384823.27098.python-list@python.org> |
| In reply to | #32923 |
On Nov 7, 2012, at 11:51 PM, Andrew Robinson <andrew3@r3dsolutions.com> wrote: > On 11/07/2012 04:00 PM, Steven D'Aprano wrote: >> 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? > Date has been corrected since two days ago. It will remain until a reboot.... > Ignorance, though, might be bliss... > >> 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. > I think the "Call by foo" came into vogue around the time of C++; Eg: It's in books like C++ for C programmers; I never saw it used before then so I *really* don't know for sure… > Just as an aside - there is a famous quote from Niklaus Wirt, who, when asked how he pronounced his name, is said to have replied: "Well you can call me by name, Veert, or you can call me by value, Worth." That would have been sometime in the early 60s, when he was at Stanford. -Bill
[toc] | [prev] | [next] | [standalone]
| From | Andrew Robinson <andrew3@r3dsolutions.com> |
|---|---|
| Date | 2012-11-07 16:24 -0800 |
| Message-ID | <mailman.3413.1352334232.27098.python-list@python.org> |
| In reply to | #32811 |
On 11/07/2012 01:01 PM, Ian Kelly wrote: > 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. It already is :) > > 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. Not quite; Although I wasn't clear; The variable passed in is by *value* in contradistinction to the list which is by reference. Python does NOT always default copy by reference *when it could*; that's the point. Hence the programmer has to remember in foo( x,y ), the names x and y when assigned to -- *DONT* affect the variables from which they came. But any object internals do affect the objects everywhere. A single exception exists; My thesis is for a single exception as well -- I think Python allows that kind of thinking. > So actually I did address > this point with the "call-by-object" tangent; I just did not > explicitly link it back to your thesis. My apology for not proof reading my statements for clarity. It was definitely time for a nap back then. > 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. I would do it again. Other's have already begun to discuss terminology with you -- I won't double team you.
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2012-11-08 04:20 +0000 |
| Message-ID | <509b3308$0$29885$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #32925 |
On Wed, 07 Nov 2012 16:24:22 -0800, Andrew Robinson wrote:
> On 11/07/2012 01:01 PM, Ian Kelly wrote:
[...]
>> 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.
>
> Not quite; Although I wasn't clear; The variable passed in is by
> *value* in contradistinction to the list which is by reference. Python
> does NOT always default copy by reference *when it could*; that's the
> point.
It isn't clear to me whether you are describing what you think Python
*actually* does, versus what you wish it *would* do, or what it *could*
do in some abstract hypothetical sense.
It certainly is not true that Python passes "the variable" by value, and
lists "by reference". Arguments are not passed to functions either by
value or by reference.
There is a trivial test for pass-by-value semantics: does the value get
copied? We can see that Python does not copy arguments:
py> def test(x):
... print id(x)
...
py> spam = []
py> print id(spam); test(spam)
3071264556
3071264556
The argument is not copied, therefore Python is not pass-by-value.
There is also an easy test for pass-by-reference semantics: can you write
a procedure which, given two variables, swaps the contents of the
variables? In Pascal, that is trivial.
procedure swap(var a: int, var b: int):
var
tmp: int;
begin
tmp := a;
a := b;
b := a;
end;
swap(x, y);
(if I've remembered my Pascal syntax correctly).
In Python, you can swap two values like this:
a, b = b, a
but that's not sufficient. The test is to do the swap inside a function:
def swap(a, b):
return b, a
b, a = swap(a, b)
But that fails too, since the assignment is still taking place outside
the function.
It turns out that there is no way in Python to write such a swap
function. Tricks such as passing the variable names as strings, then
using exec, are hacks and don't count. Python is not pass by reference
either.
> Hence the programmer has to remember in foo( x,y ), the names x and y
> when assigned to -- *DONT* affect the variables from which they came.
> But any object internals do affect the objects everywhere.
Ummm.... yes?
The programmer has to remember Python's execution model in order to
correctly predict what Python will do. What's your point?
> A single exception exists;
There is no such exception in Python. Python always uses the same
argument passing (parameter binding) semantics.
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2012-11-06 17:07 +1100 |
| Message-ID | <mailman.3312.1352182028.27098.python-list@python.org> |
| In reply to | #32762 |
On Tue, Nov 6, 2012 at 4:51 PM, Andrew Robinson <andrew3@r3dsolutions.com> wrote: > I really don't think doing a shallow copy of lists would break anyone's > program. Well, it's a change, a semantic change. It's almost certainly going to break _something_. But for the sake of argument, we can suppose that the change could be made. Would it be the right thing to do? Shallow copying by default would result in extremely weird behaviour. All the same confusion would result, only instead of comparing [None]*4 with [[None]]*4, there'd be confusion over the difference between [[None]]*4 and [[[None]]]*4. I don't think it would help anything, and it'd result in a lot more work for no benefit. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Andrew Robinson <andrew3@r3dsolutions.com> |
|---|---|
| Date | 2012-11-06 00:21 -0800 |
| Message-ID | <mailman.3313.1352190429.27098.python-list@python.org> |
| In reply to | #32762 |
On 11/05/2012 10:07 PM, Chris Angelico wrote: > On Tue, Nov 6, 2012 at 4:51 PM, Andrew Robinson > <andrew3@r3dsolutions.com> wrote: >> I really don't think doing a shallow copy of lists would break anyone's >> program. > Well, it's a change, a semantic change. It's almost certainly going to > break _something_. But for the sake of argument, we can suppose that > the change could be made. Would it be the right thing to do? > > Shallow copying by default would result in extremely weird behaviour. > All the same confusion would result, only instead of comparing > [None]*4 with [[None]]*4, there'd be confusion over the difference > between [[None]]*4 and [[[None]]]*4. > > I don't think it would help anything, and it'd result in a lot more > work for no benefit. > > ChrisA I don't follow. a=[ None ]*4 would give a=[ None, None, None, None ] as usual. All four None's would be the same object, but there are automatically 4 different pointers to it. Hence, a[0]=1 would give a=[ 1, None, None, None ] as usual. a=[ [None] ]*4 would give a=[ [None], [None], [None], [None] ] as usual BUT: a[0][0] = 1 would no longer give a=[ [1],[1],[1],[1] ] *Rather* it would give a=[ [1].[None].[None],[None] ] The None objects are all still the same one, BUT the lists themselves are different. Again, a=[ ["alpha","beta"] * 4 ] would give: a=[ ["alpha","beta"], ["alpha","beta"], ["alpha","beta"], ["alpha","beta"] ] All four strings, "alpha", are the same object -- but there are 5 different lists; The pointers inside the initial list are copied four times -- not the string objects; But the *lists* themselves are created new for each replication. If you nest it another time; [[[None]]]*4, the same would happen; all lists would be independent -- but the objects which aren't lists would be refrenced-- not copied. a=[[["alpha","beta"]]]*4 would yield: a=[[['alpha', 'beta']], [['alpha', 'beta']], [['alpha', 'beta']], [['alpha', 'beta']]] and a[0][0]=1 would give [[1],[['alpha', 'beta']], [['alpha', 'beta']], [['alpha', 'beta']]]] rather than a=[[1], [1], [1], [1]] Or at another level down: a[0][0][0]=1 would give: a=[[[1, 'beta']], [['alpha', 'beta']], [['alpha', 'beta']], [['alpha', 'beta']] ] rather than a=[[[1, 'beta']], [[1, 'beta']], [[1, 'beta']], [[1, 'beta']]] The point is, there would be no difference at all noticed in what data is found where in the array; the *only* thing that would change is that replacing an item by assignment would only affect the *location* assigned to -- all other locations would not be affected. That really is what people *generally* want. If the entire list is meant to be read only -- the change would affect *nothing* at all. See if you can find *any* python program where people desired the multiplication to have the die effect that changing an object in one of the sub lists -- changes all the objects in the other sub lists. I'm sure you're not going to find it -- and even if you do, it's going to be 1 program in 1000's.
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2012-11-06 02:19 -0700 |
| Message-ID | <mailman.3316.1352193584.27098.python-list@python.org> |
| In reply to | #32762 |
On Tue, Nov 6, 2012 at 1:21 AM, Andrew Robinson <andrew3@r3dsolutions.com> wrote: > If you nest it another time; > [[[None]]]*4, the same would happen; all lists would be independent -- but > the objects which aren't lists would be refrenced-- not copied. > > a=[[["alpha","beta"]]]*4 would yield: > a=[[['alpha', 'beta']], [['alpha', 'beta']], [['alpha', 'beta']], [['alpha', > 'beta']]] > and a[0][0]=1 would give [[1],[['alpha', 'beta']], [['alpha', 'beta']], > [['alpha', 'beta']]]] > rather than a=[[1], [1], [1], [1]] > > Or at another level down: a[0][0][0]=1 would give: a=[[[1, 'beta']], > [['alpha', 'beta']], [['alpha', 'beta']], [['alpha', 'beta']] ] > rather than a=[[[1, 'beta']], [[1, 'beta']], [[1, 'beta']], [[1, 'beta']]] You wrote "shallow copy". When the outer-level list is multiplied, the mid-level lists would be copied. Because the copies are shallow, although the mid-level lists are copied, their contents are not. Thus the inner-level lists would still be all referencing the same list. To demonstrate: >>> from copy import copy >>> class ShallowCopyList(list): ... def __mul__(self, number): ... new_list = ShallowCopyList() ... for _ in range(number): ... new_list.extend(map(copy, self)) ... return new_list ... >>> a = ShallowCopyList([[["alpha", "beta"]]]) >>> a [[['alpha', 'beta']]] >>> b = a * 4 >>> b [[['alpha', 'beta']], [['alpha', 'beta']], [['alpha', 'beta']], [['alpha', 'beta']]] >>> b[0][0][0] = 1 >>> b [[[1, 'beta']], [[1, 'beta']], [[1, 'beta']], [[1, 'beta']]] >>> b[0][0] = 1 >>> b [[1], [[1, 'beta']], [[1, 'beta']], [[1, 'beta']]] This shows that assignments at the middle level are independent with a shallow copy on multiplication, but assignments at the inner level are not. In order to achieve the behavior you describe, a deep copy would be needed. > That really is what people *generally* want. > If the entire list is meant to be read only -- the change would affect > *nothing* at all. The time and memory cost of the multiplication operation would become quadratic instead of linear. > See if you can find *any* python program where people desired the > multiplication to have the die effect that changing an object in one of the > sub lists -- changes all the objects in the other sub lists. > > I'm sure you're not going to find it -- and even if you do, it's going to be > 1 program in 1000's. Per the last thread where we discussed extremely rare scenarios, shouldn't you be rounding "1 in 1000s" up to 20%? ;-)
[toc] | [prev] | [next] | [standalone]
| From | "Prasad, Ramit" <ramit.prasad@jpmorgan.com> |
|---|---|
| Date | 2012-11-06 17:32 +0000 |
| Message-ID | <mailman.3334.1352223730.27098.python-list@python.org> |
| In reply to | #32762 |
Ian Kelly wrote: > > On Tue, Nov 6, 2012 at 1:21 AM, Andrew Robinson > [snip] > > See if you can find *any* python program where people desired the > > multiplication to have the die effect that changing an object in one of the > > sub lists -- changes all the objects in the other sub lists. > > > > I'm sure you're not going to find it -- and even if you do, it's going to be > > 1 program in 1000's. > > Per the last thread where we discussed extremely rare scenarios, > shouldn't you be rounding "1 in 1000s" up to 20%? ;-) Actually, I would be surprised if it was even 1 in 1000. Of course, consistency makes it easier to learn and *remember*. I value that far more than a minor quirk that is unlikely to bother me now that I know of it. Well, at least not as long as I do not forget my morning coffee/tea :) ~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]
| From | Andrew Robinson <andrew3@r3dsolutions.com> |
|---|---|
| Date | 2012-11-06 13:14 -0800 |
| Message-ID | <mailman.3339.1352236812.27098.python-list@python.org> |
| In reply to | #32762 |
On 11/06/2012 06:35 AM, Oscar Benjamin wrote: > > > In general, people don't use element multiplication (that I have > *ever* seen) to make lists where all elements of the outer most list > point to the same sub-*list* by reference. The most common use of the > multiplication is to fill an array with a constant, or short list of > constants; Hence, almost everyone has to work around the issue as > the initial poster did by using a much longer construction. > > That's what I have seen as well. I've never seen an example where > someone wanted this behaviour. > > > > > The most compact notation in programming really ought to reflect the > most *commonly* desired operation. Otherwise, we're really just > making people do extra typing for no reason. > > It's not so much the typing as the fact that this a common gotcha. > Apparently many people expect different behaviour here. I seem to > remember finding this surprising at first. > :) That's true as well. > > > > > Further, list comprehensions take quite a bit longer to run than low > level copies; by a factor of roughly 10. SO, it really would be worth > implementing the underlying logic -- even if it wasn't super easy. > > > > I really don't think doing a shallow copy of lists would break > anyone's program. > > The non-list elements, whatever they are, can be left as reference > copies -- but any element which is a list ought to be shallow copied. > The behavior observed in the opening post where modifying one element > of a sub-list, modifies all elements of all sub-lists is never desired > as far as I have ever witnessed. > > It is a semantic change that would, I imagine, break many things in > subtle ways. > ?? Do you have any guesses, how ? > > > > > The underlying implementation of Python can check an object type > trivially, and the only routine needed is a shallow list copy. So, no > it really isn't a complicated operation to do shallow copies of lists. > > Yes but if you're inspecting the object to find out whether to copy it > what do you test for? If you check for a list type what about > subclasses? What if someone else has a custom list type that is not a > subclass? Should there be a dunder method for this? > No dunder methods. :) Custom non-subclass list types aren't a common usage for list multiplication in any event. At present one has to do list comprehensions for that, and that would simply remain so. Subclasses, however, are something I hadn't considered... > I don't think it's such a simple problem. > > Oscar > You made a good point, Oscar; I'll have to think about the subclassing a bit. :)
[toc] | [prev] | [next] | [standalone]
| From | Andrew Robinson <andrew3@r3dsolutions.com> |
|---|---|
| Date | 2012-11-06 13:19 -0800 |
| Message-ID | <mailman.3340.1352237153.27098.python-list@python.org> |
| In reply to | #32762 |
On 11/06/2012 09:32 AM, Prasad, Ramit wrote: > Ian Kelly wrote: >> On Tue, Nov 6, 2012 at 1:21 AM, Andrew Robinson >> > [snip] >>> See if you can find *any* python program where people desired the >>> multiplication to have the die effect that changing an object in one of the >>> sub lists -- changes all the objects in the other sub lists. >>> >>> I'm sure you're not going to find it -- and even if you do, it's going to be >>> 1 program in 1000's. >> Per the last thread where we discussed extremely rare scenarios, >> shouldn't you be rounding "1 in 1000s" up to 20%? ;-) :D -- Ian -- also consider that I *am* willing to use extra memory. Not everything can be shrunk to nothing and still remain functional. :) So, it isn't *all* about *micro* optimization -- it's also about psychology and flexibility. > Actually, I would be surprised if it was even 1 in 1000. > Of course, consistency makes it easier to learn and *remember*. > I value that far more than a minor quirk that is unlikely to > bother me now that I know of it. Well, at least not as long as > I do not forget my morning coffee/tea :) But, having it copy lists -- when the only purpose of multiplication is for lists; is only a minor quirk as well. > > > ~Ramit
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2012-11-06 15:46 -0700 |
| Message-ID | <mailman.3342.1352242045.27098.python-list@python.org> |
| In reply to | #32762 |
On Tue, Nov 6, 2012 at 2:36 PM, Andrew Robinson
<andrew3@r3dsolutions.com> wrote:
> I meant all lists are shallow copied from the innermost level out.
> Equivalently, it's a deep copy of list objects -- but a shallow copy of any list contents except other lists.
Why only list objects, though? When a user writes [[]] * 10, they
probably want a list containing ten distinct nested lists. Likewise,
when a user writes [{}] * 10, they probably want a list containing ten
distinct dicts, which is not at all an uncommon thing to want. It
seems very inconsistent that the former should work while the latter
should not. This is especially true when you start mixing the two
paradigms; the user might expect [[{}] * 10] * 10 to create a a 10x10
matrix where each element is a distinct dict, but this still would not
work, even though the nested lists would all have different
identities.
What about ([],) * 10? This is perhaps best interpreted as a request
to create a matrix of ten rows where the rows themselves are mutable
but the collection of rows is not. If list multiplication were to
copy nested lists, then should tuple multiplication do the same?
[toc] | [prev] | [next] | [standalone]
| From | Gregory Ewing <greg.ewing@canterbury.ac.nz> |
|---|---|
| Date | 2012-11-07 18:34 +1300 |
| Message-ID | <afua6hFbj9gU2@mid.individual.net> |
| In reply to | #32844 |
If anything is to be done in this area, it would be better as an extension of list comprehensions, e.g. [[None times 5] times 10] which would be equivalent to [[None for _i in xrange(5)] for _j in xrange(10)] -- Greg
[toc] | [prev] | [next] | [standalone]
| From | Oscar Benjamin <oscar.j.benjamin@gmail.com> |
|---|---|
| Date | 2012-11-07 14:00 +0000 |
| Message-ID | <mailman.3371.1352296829.27098.python-list@python.org> |
| In reply to | #32870 |
On 7 November 2012 13:39, Joshua Landau <joshua.landau.ws@gmail.com> wrote: > > On 7 November 2012 11:11, Oscar Benjamin <oscar.j.benjamin@gmail.com> wrote: >> >> A more modest addition for the limited case described in this thread could >> be to use exponentiation: >> >> >>> [0] ** (2, 3) >> [[0, 0, 0], [0, 0, 0]] > > Hold on: why not just use multiplication? > >>>> [0] * (2, 3) > > is an error now, and it makes total sense. Additionally, it's not breaking > the "no copy -- _ever_" rule because none of the lists existed before. The > values inside the list would be by reference, as before, so lst * (x,) would > be the same as lst * x if x is an integer. The problem is that this operation is asymmetric. Currently int/list multiplication is commutative so that: ['a', 'b'] * 2 == 2 * ['a', 'b'] If you use this kind of multiplication what happens to the other cases? e.g. what do you give for: >>> [0] * [2, 3] >>> [2, 3] * [0] >>> (2, 3) * [0] >>> (2, 3) * (4, 5) and so on. Although Python does not guarantee commutativity of multiplication in general I think that since for lists it has always been commutative it would be bad to change that. Exponentiation is expected to be asymmetric and is currently unused so there is no ambiguity. The problem is if someone has already subclassed list and added an exponentiation method. Oscar
[toc] | [prev] | [next] | [standalone]
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2012-11-07 06:47 -0800 |
| Message-ID | <mailman.3373.1352303560.27098.python-list@python.org> |
| In reply to | #32870 |
Oscar Benjamin wrote:
> On Nov 7, 2012 5:41 AM, "Gregory Ewing" <greg.ewing@canterbury.ac.nz
> <mailto:greg.ewing@canterbury.ac.nz>> wrote:
> >
> > If anything is to be done in this area, it would be better
> > as an extension of list comprehensions, e.g.
> >
> > [[None times 5] times 10]
> >
> > which would be equivalent to
> >
> > [[None for _i in xrange(5)] for _j in xrange(10)]
>
> I think you're right that the meaning of list-int multiplication
> can't/shouldn't be changed if this way.
>
> A multidimensional list comprehension would be useful even for people
> who are using numpy as it's common to use a list comprehension to
> initialise a numpy array.
>
> A more modest addition for the limited case described in this thread
> could be to use exponentiation:
>
> >>> [0] ** (2, 3)
> [[0, 0, 0], [0, 0, 0]]
What would happen with
--> [{}] ** (2, 3)
or
--> [my_custom_container()] ** (2, 3)
?
~Ethan~
[toc] | [prev] | [next] | [standalone]
| From | Oscar Benjamin <oscar.j.benjamin@gmail.com> |
|---|---|
| Date | 2012-11-07 23:06 +0000 |
| Message-ID | <mailman.3399.1352329595.27098.python-list@python.org> |
| In reply to | #32870 |
On 7 November 2012 22:16, Joshua Landau <joshua.landau.ws@gmail.com> wrote: > On 7 November 2012 14:00, Oscar Benjamin <oscar.j.benjamin@gmail.com> wrote: >> On 7 November 2012 13:39, Joshua Landau <joshua.landau.ws@gmail.com> >> wrote: >> > On 7 November 2012 11:11, Oscar Benjamin <oscar.j.benjamin@gmail.com> >> > wrote: >> >> A more modest addition for the limited case described in this thread >> >> could >> >> be to use exponentiation: >> >> >> >> >>> [0] ** (2, 3) >> >> [[0, 0, 0], [0, 0, 0]] >> >> Exponentiation is expected to be asymmetric and is currently unused so >> there is no ambiguity. The problem is if someone has already >> subclassed list and added an exponentiation method. > > How is that a problem? They just wont get the functionality. This is absolutely contrived but: Library A defines a subclass of list that adds an exponentiation operator thinking that it's okay to still use these objects as lists. Library B has an API that expects a list and tries to use the list copy-exponentiation on its input. A user passes a list type object from library A into library B and hopefully gets an error but possibly gets a subtle bug that is hard to track down. It doesn't sound plausible to me but at least in principle there is a backward compatibility problem. > That said, losing: > [0] * (2, 3) == [0] * [2, 3] > would mean losing duck-typing in general. *Thus*, I fully agree with your > choice of exponentiation. Also there's no reason why tuples couldn't have the same exponentiation operator (although for them it would be no different from repeated multiplication). Oscar
[toc] | [prev] | [next] | [standalone]
| From | Greg Ewing <greg.ewing@canterbury.ac.nz> |
|---|---|
| Date | 2012-11-08 14:29 +1300 |
| Message-ID | <mailman.3417.1352338205.27098.python-list@python.org> |
| In reply to | #32870 |
On 08/11/12 12:06, Oscar Benjamin wrote: > On 7 November 2012 22:16, Joshua Landau<joshua.landau.ws@gmail.com> wrote: >> That said, losing: >> [0] * (2, 3) == [0] * [2, 3] >> would mean losing duck-typing in general. There are precedents for this kind of thing; the string % operator treats tuples specially, for example. I don't think it's all that bad if you regard the tuple as effectively part of the syntax. -- Greg
[toc] | [prev] | [next] | [standalone]
| From | wxjmfauth@gmail.com |
|---|---|
| Date | 2012-11-05 01:55 -0800 |
| Message-ID | <d5a065c4-163a-416f-b75d-f73ce66ec35c@googlegroups.com> |
| In reply to | #32748 |
Le lundi 5 novembre 2012 07:28:00 UTC+1, Demian Brecht a écrit : > 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. > > > > Demian Brecht > > @demianbrecht > > http://demianbrecht.github.com ---------- You probably mean a two-dimensional matrix not a 4D matrix. >>> def DefMatrix(nrow, ncol, val): ... return [[val] * ncol for i in range(nrow)] ... >>> aa = DefMatrix(2, 3, 1.0) >>> aa >>> aa = DefMatrix(2, 3, 1.0) >>> aa [[1.0, 1.0, 1.0], [1.0, 1.0, 1.0]] >>> aa[0][0] = 3.14 >>> aa[1][2] = 2.718 >>> aa [[3.14, 1.0, 1.0], [1.0, 1.0, 2.718]] >>> >>> bb = DefMatrix(2, 3, None) >>> bb [[None, None, None], [None, None, None]] >>> bb[0][0] = 3.14 >>> bb[1][2] = 2.718 >>> bb [[3.14, None, None], [None, None, 2.718]] jmf
[toc] | [prev] | [standalone]
Page 3 of 3 — ← Prev page 1 2 [3]
Back to top | Article view | comp.lang.python
csiph-web