Dick Moores wrote: > At 07:34 PM 8/22/2007, Kent Johnson wrote: >> FWIW here is my fastest solution: >> >> 01 from itertools import chain >> 02 def compute(): >> 03 str_=str; int_=int; slice_=slice(None, None, -1) >> 04 for x in chain(xrange(1, 1000001, 10), xrange(2, 1000001, 10), >> 05 xrange(3, 1000001, 10), xrange(4, 1000001, 10), xrange(5, 1000001, 10), >> 06 xrange(6, 1000001, 10), xrange(7, 1000001, 10), xrange(8, 1000001, 10), >> 07 xrange(9, 1000001, 10)): >> 08 rev = int_(str_(x)[slice_]) >> 09 if rev>=x: continue >> 10 if not x % rev: >> 11 print x, >> 12 compute()
> And at first I thought your use of str_, int_, and slice_ were pretty > weird; instead of your line 08, why not just use the straightforward > > rev = int(str(x)[::-1]) > > but on upon testing I see they all make their respective > contributions to speed. > > But I don't understand why. Why is your line 08 faster than "rev = > int(str(x)[::-1])"? Two reasons. First, looking up a name that is local to a function is faster than looking up a global name. To find the value of 'str', the interpreter has to look at the module namespace, then the built-in namespace. These are each dictionary lookups. Local values are stored in an array and accessed by offset so it is much faster. Second, the slice notation [::-1] actually creates a slice object and passes that to the __getitem__() method of the object being sliced. The slice is created each time through the loop. My code explicitly creates and caches the slice object so it can be reused each time. > > BTW I also thought that > > for x in chain(xrange(1, 1000001, 10), xrange(2, 1000001, 10), > xrange(3, 1000001, 10), xrange(4, 1000001, 10), xrange(5, 1000001, 10), > xrange(6, 1000001, 10), xrange(7, 1000001, 10), xrange(8, 1000001, 10), > xrange(9, 1000001, 10)): > pass > > MUST take longer than > > for x in xrange(1000000): > pass > > because there appears to be so much more going on, but their timings > are essentially identical. Well for one thing it is looping 9/10 of the number of iterations. Also, chain() doesn't have to do much, it just forwards the values returned by the underlying iterators to the caller, and all the itertools methods are written in C to be fast. If you read comp.lang.python you will often see creative uses of itertools in optimizations. Kent _______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor