number generator
Dick Moores
rdm at rcblue.com
Tue Mar 13 22:29:43 EDT 2007
At 06:20 PM 3/13/2007, Paul Rubin wrote:
>Dick Moores <rdm at rcblue.com> writes:
> > I understand what zip() and random.sample() are doing, and the above
> > helps me get inside the fencepost method, but I don't understand WHY
> > it works, or how in the world anyone could have devised it. It is
> > truly magical to me!
>
>It's Gerald Flanagan's telegraph pole method that you quoted (I
>misremembered it as "fencepost"):
>
> "Suppose you have a fixed telegraph pole at N and a fixed telegraph
> pole at M, and you're given 5 more telegraph poles..." (Gerard Flanagan),
>
>Consider this diagram for the numbers from 1 to 50:
>
> |--------------------------------------------------|
>
>The vertical bar at the left represents 0 and the vertical bar
>at the right represents 51. The fifty dashes represent 1,2,3...50.
>You can also view the fifty dashes as a line segment of length 50.
>
>The fencepost method is to simply chop the line segment into smaller
>pieces. You do that by choosing some random points inside the segment:
>
> >>> import random
> >>> random.sample(xrange(1,50), 4)
> [49, 37, 22, 5]
>
>so mark those points with plus signs (let's see if I got this right)
>and label the points from left to right, calling them p0,p1,p2,p3:
>
> |----+----------------+--------------+-----------+-|
> p0 p1 p2 p3
>
>So the length of the leftmost small segment is p0-0, the length of the
>second segment is p1-p0, the third is p2-p1, the fourth is p3-p2, and
>the fifth is 50-p3. So those lengths are the numbers you want.
>
>The zip thing was just a way to avoid using messy subscripts to
>compute the lengths. Another way to do it is (untested):
>
> t2 = [0] + t + [50]
> lst = [(t2[i] - t2[i-1]) for i in xrange(1, len(t2))]
Works fine!
>I'm not sure which is better from a Python stylistic perspective.
I'm not sure, but I think if you had written it this way at first, I
would have understood it. But I'm glad to have learned the zip way!
>Using zip that way is fairly natural in Haskell, which I've been
>fooling around with lately. All you're doing is subtracting adjacent
>elements by making two versions of the list, one of them shifted over
>one place, then subtracting element by element, instead of jumping
>around inside a single list, with more ways to make off-by-one errors.
>It looked more symmetrical in the Python code so I did it that way.
Thank you, thank you! You've made it very clear up to this point.
I'll worry about the Haskell approach later, much later. ;)
Dick Moores
>FWIW, the actual Haskell approach would translate to something more like:
>
> from itertools import chain, izip
> lst = [(j-i) for i,j in izip(chain([0],t), chain(t,[50]))]
>
>which avoids making the intermediate zipped list.
More information about the Python-list
mailing list