Re: [Tutor] .__mul__

2013-08-03 Thread Alan Gauld

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__

2013-08-03 Thread Dave Angel
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

2013-08-03 Thread Dominik George
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

2013-08-03 Thread Steven D'Aprano

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