Re: [Tutor] .__mul__
On 03/08/13 15:50, Albert-Jan Roskam wrote: Suppose I initialize a list (letÅ› say it's a record) to e.g all zeroes, > or all sixes. Suppose, further, that I use "*" for this (which is a nice an clean way). Its only nice if you use it at the top level with an immutable value, otherwise , as you can see, it quickly becomes not nice and not clean. Use a list comprehension instead y = [[6] for i in range(4)] As the name suggests list comprehensions are designed for building lists. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] .__mul__
Albert-Jan Roskam wrote: > > Thank you. If list.__mul__ is so tricky, why did they implement it the way > they did? Are there situations where this behavior could be useful? > > Btw, this is one of the rare (very, very rare) cases where I find CRAN R > better than Python: Using "multiply" to pre-fill a list is very useful, and it's harmless if the value used is immutable, which it usually is. And the problem described in this thread is not specific to a list being filled with multiply.. Any time you bind the same mutable value to multiple places, you need to be aware that changing one of them changes them all. But this behavior is much safer than the alternative, not to mention faster and more memory efficient. Further, if the alternative (copy) were the default, it would require a new syntax to specify that you don't want a copy. Most languages I know of have the same duality, but they expose it differently. And in many cases, you can hide the behavior under the declarations. So you have tricky declarations and if you get them wrong, there are nasty surprises in store. For example in C++, you can declare a variable as a refernece to another one. Now when you use the first variable, you get value of the second one, changed or not. But if you forget the & in the declaration, the behavior changes in a subtle way, perhaps far from the place you made the declaration. One thing that Python does differently is that it *allows* you to change what something references. By being less restrictive than C++, you get more power. And more responsibility. -- Signature file not found ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] re module- puzzling results when matching money
Hi, \b is defined as all non-word characters, so it is the complement oft \w. \w is [A-Za-z0-9_-], so \b includes \$ and thus cuts off your group. -nik Alex Kleider schrieb: >#!/usr/bin/env python > >""" >I've been puzzling over the re module and have a couple of questions >regarding the behaviour of this script. > >I've provided two possible patterns (re_US_money): >the one surrounded by the 'word boundary' meta sequence seems not to >work >while the other one does. I can't understand why the addition of the >word >boundary defeats the match. > >I also don't understand why the split method includes the matched text. >Splitting only works as I would have expected if no goupings are used. > >If I've set this up as intended, the full body of this e-mail should be >executable as a script. > >Comments appreciated. >alex kleider >""" > ># file : tutor.py (Python 2.7, NOT Python 3) >print 'Running "tutor.py" on an Ubuntu Linux machine. *' > >import re > >target = \ >"""Cost is $4.50. With a $.30 discount: >Price is $4.15. >The price could be less, say $4 or $4. >Let's see how this plays out: $4.50.60 >""" > ># Choose one of the following two alternatives: >re_US_money =\ >r"((?P\$)(?P\d{0,})(?:\.(?P\d{2})){0,1})" ># The above provides matches. ># The following does NOT. ># re_US_money =\ ># r"\b((?P\$)(?P\d{0,})(?:\.(?P\d{2})){0,1})\b" > >pat_object = re.compile(re_US_money) >match_object = pat_object.search(target) >if match_object: > print "'match_object.group()' and 'match_object.span()' yield:" > print match_object.group(), match_object.span() > print >else: > print "NO MATCH FOUND!!!" >print >print "Now will use 'finditer()':" > >print >iterator = pat_object.finditer(target) >i = 1 >for iter in iterator: > print > print "iter #%d: "%(i, ), > print iter.group() > print "'groups()' yields: '%s'."%(iter.groups(), ) > print iter.span() > i += 1 > sign = iter.group("sign") > dollars = iter.group("dollars") > cents = iter.group("cents") > print sign, > print " ", > if dollars: > print dollars, > else: > print "00", > print " ", > if cents: > print cents, > else: > print "00", > >print > >t = target >sub_target = pat_object.sub("", t) >print >print "Printing substitution: " >print sub_target >split_target = pat_object.split(target) >print "Result of splitting on the target: " >print split_target > ># End of script. >___ >Tutor maillist - Tutor@python.org >To unsubscribe or change subscription options: >http://mail.python.org/mailman/listinfo/tutor -- Diese Nachricht wurde von meinem Android-Mobiltelefon mit K-9 Mail gesendet.___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] range as a not-quite-iterator
On 04/08/13 11:14, Jim Mooney wrote: using py3.3 on win7 I'm reading the Lutz book, and he clearly calls range an iterator in the context of Python 3.0, yet when I try x = range(1,10) next(x) I get: builtins.TypeError: 'range' object is not an iterator And x itself is returned as: range(1, 10) What am I missing here? Is it an iterator or not? Technically, no. Informally, yes. Technically, there are three rules for something to be an iterator: * it must have an __iter__ method which returns itself; * it must have a __next__ method which returns each subsequent value; * if there are no more values, it must raise StopIteration (this is called the "iterator protocol"). In addition, well-behaved iterators must continue to always return StopIteration once they have become empty. An iterator that becomes empty, then becomes non-empty, is officially deemed to be "broken", although you are permitted to write broken iterators if you insist. So by this definition, range (or xrange in Python 2.x) is not an iterator, since it doesn't follow the iterator protocol. However, it does behave like an iterator, in the sense that it is a lazily generated sequence, so informally, it sometimes gets called one. If it quacks like an iterator, you can treat it as an iterator. Note that range objects have an __iter__ which doesn't return the range object itself, but an iterator wrapper around itself: py> r = range(2, 45, 3) py> it = iter(r) # calls __iter__ internally py> it is r False py> it py> r range(2, 45, 3) That wrapper object actually is a genuine iterator: py> iter(it) is it True The reason for this is partly historical (xrange goes all the way back to Python 1.4 or even older, while iterators only go back to about 2.2, if I remember correctly) and partly practical -- iterators can normally be used only once, while range objects can be re-used, and also can be sliced almost like a list. py> r[1:3] range(5, 11, 3) -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor