[Python-ideas] Set starting point for itertools.product()

Ronie Martinez ronmarti18 at gmail.com
Fri Oct 26 00:16:55 EDT 2018


Hi Serhiy,

__setstate__() made it possible to specify the starting point.

Using this method and combining it with binning (if the items does not have
any pattern) worked well!

Thanks for the suggestion.

Cheers!

Best Regards,
Ronie

On Fri, Oct 26, 2018 at 10:31 AM Ronie Martinez <ronmarti18 at gmail.com>
wrote:

> Hi Serhiy,
>
> I missed the 31st on days range. Thanks for spotting it. I do verify if
> the datetime tuple is correct by passing them to datetime() and raising
> exception later on on the code (see
> https://github.com/Code-ReaQtor/DocCron/blob/1.0.0/doccron/job.py#L180)
>
> Datetime and timedeltas can solve the problem if there is a "pattern" but
> this is not an efficient way.
>
> For example, if there are steps on all the categories or the items have no
> pattern:
>
> datetime_odometer = itertools.product(
>     range(2018, 10_000, 5),  # year with steps
>     range(1, 13, 3),  # month with steps
>     range(1, 32, 4),  # days with steps
>     [0, 5, 6, 10, 13, 24],  # hours without steps
>     range(0, 60, 6),  # minutes with steps
>     range(0, 60, 2)  # seconds with steps
> )
>
>
> Datetime and timedelta will create a lot of overhead and is not the best
> solution. I still believe itertools.product() is the fastest and best
> solution.
>
> Let me read the code for __setstate__ first. Thanks for spotting this!
>
> Best Regards,
> Ronie Martinez
>
>
> On Thu, Oct 25, 2018 at 6:22 PM Serhiy Storchaka <storchaka at gmail.com>
> wrote:
>
>> 25.10.18 09:31, Ronie Martinez пише:
>> > Here is an example:
>> >
>> > import itertools
>> > import time
>> >
>> >
>> > 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
>> > )
>> >
>> >      datetime_of_interest = (2050,6,15,10,5,0)
>> >
>> >      for iin datetime_odometer:
>> >          if i == datetime_of_interest:# target start time
>> >              break
>> >
>> >
>> > if __name__ =='__main__':
>> >      start = time.time()
>> >      main()
>> >      duration = time.time() - start
>> >      print(duration,'seconds')# 91.9426908493042 seconds
>> >
>> >
>> > It took 92 seconds to get to the target start time. It does not only
>> > apply to datetimes but for other purposes that uses "odometer-like"
>> > patterns.
>> >
>> > I don't have any propose solution for now, but I guess adding this
>> > feature within itertools will come in handy.
>>
>> Thank you for clarification. Now I understand your idea.
>>
>> For datetimes it is better to use the datetime classes:
>>
>> def iterdatetimes():
>>      delta = timedelta(microseconds=1)
>>      dt = datetime(2050,6,15,10,5,0)
>>      while True:
>>          yield dt
>>          dt += delta
>>
>> Note that in your example you missed 31th days, but iterate 29th and
>> 30th February.
>>
>> See also the calendar module which provides date range iterators
>> (although not with microsecond precision).
>>
>> Currently for general "odometer-like" patterns you can use the
>> undocumented __setstate__ method of itertools.product. But this is on
>> your own risk.
>>
>> _______________________________________________
>> 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/1985615a/attachment-0001.html>


More information about the Python-ideas mailing list