[Python-ideas] Set starting point for itertools.product()
Ronie Martinez
ronmarti18 at gmail.com
Thu Oct 25 22:20:35 EDT 2018
Hi Steve,
I tried this when writing DocCron <https://github.com/Code-ReaQtor/DocCron>but
it will not work correctly.
Suppose we have minutes with range 0-59 and seconds with range 0-59 but
starting at, say, 5:
When the seconds value reaches 59, on the next iteration the minute value
should increase by 1 (or back to zero) but it will not work that way since
the next rotation will be at 4 transitioning to 5.
So the correct solution is not modifying any of the arrangements.
Best Regards,
Ronie
On Thu, Oct 25, 2018 at 7:31 PM Steven D'Aprano <steve at pearwood.info> wrote:
> On Thu, Oct 25, 2018 at 02:31:05PM +0800, Ronie Martinez wrote:
>
> > def main():
> > datetime_odometer = itertools.product(
> > range(2018, 10_000), # year
> > range(1, 13), # month
> > range(1, 31), # days
> > range(0, 24), # hours
> > range(0, 60), # minutes
> > range(0, 60) # seconds
> > )
>
> When you talked about datetime, I thought you meant actual datetime
> objects. The above is buggy: it ignores the 31st day of January, etc,
> but includes February 29 and 30 every year.
>
>
> > datetime_of_interest = (2050, 6, 15, 10, 5, 0)
> >
> > for i in datetime_odometer:
> > if i == datetime_of_interest: # target start time
> > break
>
> In the most general case, there is no way to jump into the middle of an
> arbitrary iterator, except to start at the beginning and compute the
> values until you see the one that you want. Arbitrary iterators compute
> their values on request, and there is no way to jump ahead except by
> inspecting each value in turn, skipping the ones you don't want.
>
> So unless I have missed something, I think what you are asking for is
> impossible except for special cases like lists.
>
> But in *this* case, modelling an odometer, that special case works:
>
> def rotate(iterable, position):
> L = list(iterable)
> return L[position:] + L[:position]
>
> Which gives us this:
>
> py> months = rotate(range(1, 13), 5)
> py> months
> [6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5]
>
> Now pass that to itertools.product.
>
> In other words, I think that the right solution here is to construct
> your iterables to start at the position you want, rather than expect
> product() to jump into the middle of the sequence. (Which may not be
> possible.)
>
>
>
> --
> Steve
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20181026/50bae306/attachment-0001.html>
More information about the Python-ideas
mailing list