Re: [Tutor] For Loop question

2008-06-27 Thread Mark Tolonen


Lie Ryan [EMAIL PROTECTED] wrote in message 
news:[EMAIL PROTECTED]

On Thu, Jun 26, 2008 at 3:18 AM, Dick Moores [EMAIL PROTECTED] wrote:

 Hi I'm learning FOR loop now, very easy too learn. But I get confused
to understand this code :

myList = [1,2,3,4]
for index in range(len(myList)):
myList[index] += 1
print myList

And the response is:
[2, 3, 4, 5]

Can you explain me as a newbie, how that code works ??



Ahhh... don't write it like that. It is not a pythonic way to use loop.

For-loop in python can loop over sequence (list, tuple, dictionary,
iterable, etc) directly (in Visual Basic, like For...Each loop), you
very rarely would need to use range/xrange for the iterator, and you
should never use len() to pass to range.

The loop would be much more simpler, and understandable this way:

myList = [1, 2, 3, 4]
outList = []
for x in myList:
   outList.append(x + 1)
print outList

or in a more elegant way, using list comprehension:

myList = [1, 2, 3, 4]
print [(x + 1) for x in myList]



The above solutions create new lists.  If a functional requirement is to 
modify the list in place, then the original is fine (on Python 2.6 and 
later) or should use xrange instead of range (on Python 2.5 or earlier, 
especially for large lists).


Another option is:

myList = [1,2,3,4]
for index,value in enumerate(myList):
   myList[index] = value + 1

-Mark


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


Re: [Tutor] Astonishing timing result

2008-06-27 Thread Dick Moores


At 05:57 AM 6/26/2008, Kent Johnson wrote:
On Thu, Jun 26, 2008 at 3:18 AM,
Dick Moores [EMAIL PROTECTED] wrote:
 I thought I'd use this to compare the 2 ways of string
concatenation. Ever
 since I began to learn Python I've been told that only one of these
is the
 proper and efficient one to use, and especially so if the string to
be
 stitched together is a very long one.
String concatenation was optimized in Python 2.4. You might like to
try this test in Python 2.3. See the last note here:

http://www.python.org/doc/2.4.4/whatsnew/node12.html#SECTION000121

Kent
Interesting. 
Instead I've tried to find out if it's true what Alex Martelli writes on
p. 484 in the section, Building up a string from pieces in
his _Python in a Nutshell_, 2nd ed., which covers Python 2.4x.
==
The single Python anti-idiom that's likeliest to kill your
program's performance, to the point that you should _never_ use it, is to
build up a large string from pieces by looping on string concatenation
statements such as big_string+=piece. Python strings
are immutable, so each such concatenation means that Python must free the
M bytes previously allocated for big_string, and allocate and fill
M+K bytes for the new version. Doing this repeatedly in a loop, you end
up with roughly O(N**2) performance, where N is the total number of
characters. More often than not, O(N**2) performance where O(N) is
available is a performance disaster. On some platforms, things may be
even bleaker due to memory fragmentation effects caused by freeing many
memory areas of progressively larger sizes.
To achieve O(N) performance, accumulate intermediate pieces in a list
rather than build up the string piece by piece. Lists, unlike strings,
are mutable, so appending to a list has O(1) performance (amortized).
Change each occurrence of big_string+=piece
into temp_list.append(piece) , Then when you're done
accumulating, use the following to build your desired string result
inO(N) time:
  big_string = ''.join(temp_list)

==

Please see

http://py77.python.pastebin.com/f324475f5. 
It's probably obvious to you what I did. But just in case it's not, I
successively modified the lines 14 and 29 so that the length of b varied
from 6,000 to 60,000,000 for both ch1() and ch2(). The outputs show that
the longer b (Martelli's big_string) is, the greater the
performance hit taken by string concatenation (function ch2() ) compared
to the other kind (function ch1() ), the time ratios ranging from
about 1 to about 9.
Dick Moores
Win XP Pro, Python 2.5.1






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


Re: [Tutor] For Loop question

2008-06-27 Thread Kent Johnson
On Fri, Jun 27, 2008 at 2:45 AM, Mark Tolonen [EMAIL PROTECTED] wrote:

 The above solutions create new lists.  If a functional requirement is to
 modify the list in place, then the original is fine (on Python 2.6 and
 later) or should use xrange instead of range (on Python 2.5 or earlier,
 especially for large lists).

range() has not changed it Python 2.6, it still returns a list. 2.6
makes only backwards-compatible changes.

The Python 2.6 docs say, The advantage of xrange() over range() is
minimal (since xrange() still has to create the values when asked for
them) except when a very large range is used on a memory-starved
machine or when all of the range's elements are never used (such as
when the loop is usually terminated with break).

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


Re: [Tutor] Astonishing timing result

2008-06-27 Thread Kent Johnson
On Fri, Jun 27, 2008 at 6:48 AM, Dick Moores [EMAIL PROTECTED] wrote:

 Instead I've tried to find out if it's true what Alex Martelli writes on p.
 484 in the section, Building up a string from pieces in his _Python in a
 Nutshell_, 2nd ed., which covers Python 2.4x.

You might be interested in this, complete with a picture:
http://personalpages.tds.net/~kent37/blog/arch_m1_2004_08.html#e55

and this followup:
http://personalpages.tds.net/~kent37/blog/arch_m1_2004_08.html#e56

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


Re: [Tutor] Astonishing timing result

2008-06-27 Thread Dick Moores

At 04:28 AM 6/27/2008, Kent Johnson wrote:

On Fri, Jun 27, 2008 at 6:48 AM, Dick Moores [EMAIL PROTECTED] wrote:

 Instead I've tried to find out if it's true what Alex Martelli writes on p.
 484 in the section, Building up a string from pieces in his _Python in a
 Nutshell_, 2nd ed., which covers Python 2.4x.

You might be interested in this, complete with a picture:
http://personalpages.tds.net/~kent37/blog/arch_m1_2004_08.html#e55

and this followup:
http://personalpages.tds.net/~kent37/blog/arch_m1_2004_08.html#e56


Good stuff, Kent!

Dick

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


[Tutor] s[len(s):len(s)] = [x] ??

2008-06-27 Thread Dick Moores
I'm very familiar with appending x to a list, s, using s.append(x), 
however, I've never understood what the docs mean by


s.append(x) same as s[len(s):len(s)] = [x]
(See http://docs.python.org/lib/typesseq-mutable.html)

Trying it,

 s = [1,2,3]
 x = 5
 s[len(s):len(s)] = [x]
 s[len(s):len(s)]
[]


I'm not enlightened. Just what do the docs mean?

Thanks,

Dick Moores

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


Re: [Tutor] s[len(s):len(s)] = [x] ??

2008-06-27 Thread Douglas Drumond

  s = [1,2,3]
  x = 5
  s[len(s):len(s)] = [x]   # (1)




 s
 [1, 2, 3, 5]

When you did s[len(s):len(s)] you got the slice begining at len(s) with end
at len(s) - 1, ie, nothing.

At step (1), len(s) = 3, so you did s[3:3] = [x]. It meant that the slice
starting at index 3 (ie, just after s' end) is (now) the list [x].
When you did it again, you got slice s[4:4], which is empty.

[]'s


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


Re: [Tutor] s[len(s):len(s)] = [x] ??

2008-06-27 Thread Dick Moores


At 06:27 PM 6/27/2008, Douglas Drumond wrote:


 s = [1,2,3]

 x = 5

 s[len(s):len(s)] =
[x] #
(1)






 s
[1, 2, 3, 5]
When you did s[len(s):len(s)] you got the slice begining at len(s) with
end at len(s) - 1, ie, nothing.
At step (1), len(s) = 3, so you did s[3:3] = [x]. It meant that the slice
starting at index 3 (ie, just after s' end) is (now) the list [x].
When you did it again, you got slice s[4:4], which is
empty.
Ah, didn't realize I was doing it again. 
Thanks very much!
Dick



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


[Tutor] local variable 'l1' referenced before assignment

2008-06-27 Thread Dick Moores


I'm puzzled by the below error msg. If I change the line in a2()
from
l1 = [1,2,3]*100
to
l1 = [1,2,3]
There is no problem. 
Why? And why isn't that line a problem for a1()?
=
def a1():
return
l1.extend(l2)
if __name__=='__main__':
l1 =
[1,2,3]*100
l2 =
[4,5,6]
from
timeit import Timer
t =
Timer(a1(), from __main__ import a1)
t1 =
t.timeit(number=10)

def a2():
l1 +=
l2
if __name__=='__main__':
l1 =
[1,2,3]*100
l2 =
[4,5,6]
from
timeit import Timer
t =
Timer(a2(), from __main__ import a2)
t2 =
t.timeit(number=10)
print t1:, t1
print t2:, t2
print t2/t1:, t2/t1
Error msg:
E:\PythonWorktiming_2_stupidsV2.py
Traceback (most recent call last):
 File E:\PythonWork\timing_2_stupidsV2.py, line 21, in
module
 t2 = t.timeit(number=10)
 File E:\Python25\lib\timeit.py, line 161, in
timeit
 timing = self.inner(it, self.timer)
 File timeit-src, line 6, in inner
 File E:\PythonWork\timing_2_stupidsV2.py, line 15, in
a2
 l1 += l2
UnboundLocalError: local variable 'l1' referenced before assignment
===
Thanks,
Dick Moores


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


Re: [Tutor] local variable 'l1' referenced before assignment

2008-06-27 Thread Douglas Drumond
In a2() you do l1 += l2, ie, l1 = l1 + l2
But if you don't have l1 defined yet, you can't add to l2
It's like:
def a2():
l1 = foo + l2


UnboundLocalError: local variable 'foo' referenced before assignment

It's because l1 (and foo at above example) is a local variable.
a1's l1 is different from a2's l1.

On Sat, Jun 28, 2008 at 01:39, Dick Moores [EMAIL PROTECTED] wrote:

  I'm puzzled by the below error msg. If I change the line in a2() from

 l1 = [1,2,3]*100

 to

 l1 = [1,2,3]

 There is no problem.

 Why? And why isn't that line a problem for a1()?

 =
 def a1():
 return l1.extend(l2)
 if __name__=='__main__':
 l1 = [1,2,3]*100
 l2 = [4,5,6]
 from timeit import Timer
 t = Timer(a1(), from __main__ import a1)
 t1 = t.timeit(number=10)


 def a2():
 l1 += l2
 if __name__=='__main__':
 l1 = [1,2,3]*100
 l2 = [4,5,6]
 from timeit import Timer
 t = Timer(a2(), from __main__ import a2)
 t2 = t.timeit(number=10)

 print t1:, t1
 print t2:, t2
 print t2/t1:, t2/t1

 Error msg:
 E:\PythonWorktiming_2_stupidsV2.py
 Traceback (most recent call last):
   File E:\PythonWork\timing_2_stupidsV2.py, line 21, in module
 t2 = t.timeit(number=10)
   File E:\Python25\lib\timeit.py, line 161, in timeit
 timing = self.inner(it, self.timer)
   File timeit-src, line 6, in inner
   File E:\PythonWork\timing_2_stupidsV2.py, line 15, in a2
 l1 += l2
 UnboundLocalError: local variable 'l1' referenced before assignment
 ===

 Thanks,

 Dick Moores

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


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