Re: [Tutor] how to *really* copy a list

2006-04-29 Thread kevin parks
John,

Thanks. Your message was very helpful. I will tattoo it to my forehead.
hehe... i notice that the learning python book also explains so of 
this
and i shall study that as well

cheers,

kevin

On Apr 27, 2006, at 10:14 PM, [EMAIL PROTECTED] wrote:

 On 28/04/06, kevin parks [EMAIL PROTECTED] wrote:
 In most case you are fine operating on the list in place and altering 
 the
 existing list. In some cases you want your code to stop molesting 
 your poor
 mutables and really honestly sincerly copy the dang thing. In this 
 case i am
 making a function that does odd smmetry mirroring. But i want my 
 orginal list
 to remain intact

 def mirror(seq):
 odd symmetry mirroring  [1, 2, 3, 4] -- [1, 2, 3, 4, 3, 
 2, 1]
 foo=seq[:-1]# copy list, 
 excluding last element for odd symetry
 foo.reverse()   # flip it
 seq.extend(foo)
 return seq

 Hi Kevin,

 Your problem is this line:
 seq.extend(foo)

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] how to *really* copy a list

2006-04-29 Thread kevin parks
Ed,

I should have realized that the nesting would create the problem, but i 
didn't have
that in mind... i always thought that the difference between extend and 
append
was that extend did not yield a nested list.

I really need to revisit this issue and get it right in my mind. It is 
a 'gotcha'
that i remember reading about often but, now that it has bit me a few 
times
hehe  so much to know...

-kevin--



On Apr 29, 2006, at 6:00 AM, [EMAIL PROTECTED] wrote:


 Hi Kevin,

 Your problem is this line:
 seq.extend(foo)

 This is the line that mutates your original list.

 There are a few ways you could procede here.  One way is to make a
 copy of the argument, like this:

 def mirror(seq):
 start = list(seq)
 end = seq[:-1]
 end.reverse()
 start.extend(end)
 return start

 Notice that we've not calling any methods on seq, so seq won't be
 changed.  The first line, start = list(seq), instructs python to
 build a new list out of the elements of seq.  You could also write
 start = seq[:] here --- I'm not sure which is the preferred way.

 A little 'gotcha' with this is that if you have nested lists, these
 methods don't copy the nested lists, only the outer list (which makes
 sense, but can be surprising the first time you encounter it).  If for
 some reason you want to copy nested lists, look into deepcopy(),
 otherwise you'll be fine.

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] how to *really* copy a list

2006-04-28 Thread Ed Singleton
On 28/04/06, John Fouhy [EMAIL PROTECTED] wrote:
 On 28/04/06, kevin parks [EMAIL PROTECTED] wrote:
  In most case you are fine operating on the list in place and altering the
  existing list. In some cases you want your code to stop molesting your poor
  mutables and really honestly sincerly copy the dang thing. In this case i am
  making a function that does odd smmetry mirroring. But i want my orginal 
  list
  to remain intact
 
  def mirror(seq):
  odd symmetry mirroring  [1, 2, 3, 4] -- [1, 2, 3, 4, 3, 2, 1]
  foo=seq[:-1]# copy list, excluding last 
  element for odd symetry
  foo.reverse()   # flip it
  seq.extend(foo)
  return seq

 Hi Kevin,

 Your problem is this line:
 seq.extend(foo)

 This is the line that mutates your original list.

 There are a few ways you could procede here.  One way is to make a
 copy of the argument, like this:

 def mirror(seq):
 start = list(seq)
 end = seq[:-1]
 end.reverse()
 start.extend(end)
 return start

 Notice that we've not calling any methods on seq, so seq won't be
 changed.  The first line, start = list(seq), instructs python to
 build a new list out of the elements of seq.  You could also write
 start = seq[:] here --- I'm not sure which is the preferred way.

A little 'gotcha' with this is that if you have nested lists, these
methods don't copy the nested lists, only the outer list (which makes
sense, but can be surprising the first time you encounter it).  If for
some reason you want to copy nested lists, look into deepcopy(),
otherwise you'll be fine.

Also, personally I think list(seq) is better than seq[:] because it
can cope with anything put into it that it could possibly work with
(even dicts and iterators).

 def i():
... for n in range(3):
... yield n
...
 list(i())
[0, 1, 2]

 d = {'a':1,'b':2}
 list(d)
['a', 'b']

 i()[:]
Traceback (most recent call last):
  File stdin, line 1, in ?
TypeError: unsubscriptable object
 d[:]
Traceback (most recent call last):
  File stdin, line 1, in ?
TypeError: unhashable type

Ed
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] how to *really* copy a list

2006-04-27 Thread kevin parks




I know there is an answer to this somewhere. it is prolly the biggest 
stumbling
block to all python n00bs, but it hasn't been an issue for me in a 
while.
Suddenly i am getting bit by it and can't for the life of me keep 
straight the
two way of opperating on lists.

In most case you are fine operating on the list in place and altering 
the
existing list. In some cases you want your code to stop molesting your 
poor
mutables and really honestly sincerly copy the dang thing. In this case 
i am
making a function that does odd smmetry mirroring. But i want my 
orginal list
to remain intact

  a = [1, 2, 3, 4]
  mirror(a)
[1, 2, 3, 4, 3, 2, 1]
  a
[1, 2, 3, 4, 3, 2, 1]

clearly this is not happening. believe it or not i googled around 
figuring the
answer would be posted someplace... but if it is i haven't found it. 
Every thing
i land on says copy a list by [:] slicing like i have below...

how to i really (not kidding) copy a list? I swear i used to know this, 
but i haven't had
to do it in a long long long time.


# ===

dumb code:

def mirror(seq):
odd symmetry mirroring  [1, 2, 3, 4] -- [1, 2, 3, 4, 3, 2, 1]
foo=seq[:-1]# copy list, excluding last 
element for odd symetry
foo.reverse()   # flip it
seq.extend(foo)
return seq


___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] how to *really* copy a list

2006-04-27 Thread John Fouhy
On 28/04/06, kevin parks [EMAIL PROTECTED] wrote:
 In most case you are fine operating on the list in place and altering the
 existing list. In some cases you want your code to stop molesting your poor
 mutables and really honestly sincerly copy the dang thing. In this case i am
 making a function that does odd smmetry mirroring. But i want my orginal list
 to remain intact

 def mirror(seq):
 odd symmetry mirroring  [1, 2, 3, 4] -- [1, 2, 3, 4, 3, 2, 1]
 foo=seq[:-1]# copy list, excluding last 
 element for odd symetry
 foo.reverse()   # flip it
 seq.extend(foo)
 return seq

Hi Kevin,

Your problem is this line:
seq.extend(foo)

This is the line that mutates your original list.

There are a few ways you could procede here.  One way is to make a
copy of the argument, like this:

def mirror(seq):
start = list(seq)
end = seq[:-1]
end.reverse()
start.extend(end)
return start

Notice that we've not calling any methods on seq, so seq won't be
changed.  The first line, start = list(seq), instructs python to
build a new list out of the elements of seq.  You could also write
start = seq[:] here --- I'm not sure which is the preferred way.

Another option is to use arithmetic --- you can add lists together,
and this creates a new list.  eg:

def mirror(seq):
end = seq[:-1]
end.reverse()
return seq + end

Finally, just a side comment: You can use slicing to reverse the end
for you as well.  So, we could rewrite the last function as:

def mirror(seq):
end = seq[-2::-1]
return seq + end

Which means there is a one-line version as well:

def mirror(seq):
return seq + seq[-2::-1]

HTH!

--
John.
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor