Re: Eliminate "extra" variable

Discussion in 'Python' started by Tim Chase, Dec 8, 2013.

  1. Tim Chase

    Tim Chase Guest

    On 2013-12-07 23:14, Igor Korot wrote:
    > def MyFunc(self, originalData):
    > self.dates = []
    > data = {}
    > dateStrs = []
    > for i in xrange(0, len(originalData)):
    > dateStr, freq, source = originalData
    > data[str(dateStr)] = {source: freq}
    > dateStrs.append(dateStr)
    > for i in xrange(0, len(dateStrs) - 1):
    > currDateStr = str(dateStrs)
    > nextDateStr = str(dateStrs[i + 1])
    > self.dates.append(currDateStr)
    > currDate = datetime.datetime.strptime(currDateStr,
    > '%Y-%m-%d') nextDate = datetime.datetime.strptime(nextDateStr,
    > '%Y-%m-%d') if nextDate - curDate < datetime.timedelta(days=31):
    > d = currDate + datetime.timedelta(days=1)
    > while d < nextDate:
    > self.dates.append(d.strftime('%Y-%m-%d'))
    > d = d + datetime.timedelta(days=1)
    > lastDateStr = dateStrs[-1]
    > self.dates.append(str(lastDateStr))
    > return data


    It would help to know what you want this function to accomplish:
    "MyFunc" isn't exactly descriptive. From what I gather by reading
    it, you want it to do two things:

    - append each date in the range from originalData[0] through
    originalData[-1] to self.dates every time this function is called
    (which means that multiple calls to this will grow self.dates
    every time)

    - if there's less than 31 days between N and N+1, also append all
    the dates in between (this seems weird, but okay). Again, every
    time this function is called.

    - return a dictionary that maps dates in the input-data to the
    associated source:freq dictionary.

    It's hard to tell what you intend to do with these results. If you
    just intend to iterate over them once, asking for associated data,
    you could even create a generator that yields the date along with
    either None or the associated data. See below for that.
    Alternatively, you can return both the dict-mapping and the date-list
    from the function:

    def f(...):
    return (the_dict, the_list)

    a_dict, a_list = f(...)

    That would prevent repeated mutation of self.dates

    > As you can see there is many conversion going on and there's
    > unneeded dateStrs which is used just to loop thru the dictionary
    > and get the 2 consecutive keys.


    The final snippet of code that I provided handles this pretty nicely
    by zipping up the staggered lists and iterating over them while
    unpacking them into sensible variable names. Unless you have a need
    to operate on the dates as string, I'd just keep them as dates
    throughout the code and only turn them into strings upon output.

    > But if you see a better way - please share.


    I'd likely incorporate Peter's sliding_window() suggestion and do
    something like the following (I commented out using a tuple for the
    values, but using a tuple/namedtuple might make more sense)

    import itertools
    def sliding_window(i):
    a, b = itertools.tee(i)
    next(b)
    return itertools.izip(a, b)

    def some_descriptive_function_name(self, original_data):
    # construct these once-per-call rather than every loop
    # or even move them out to module-scope
    ONE_DAY = datetime.timedelta(days=1)
    MONTHISH = datetime.timedelta(days=31)
    for (
    (cur_dt, cur_freq, cur_source),
    (next_dt, next_freq, next_source)
    ) in sliding_window(original_data):
    info = {cur_source: cur_freq}
    # info = (cur_source, cur_freq)
    yield cur_dt, info
    if next_dt - cur_dt < MONTHISH:
    d = cur_dt + ONE_DAY
    while d < next_dt:
    yield d, None
    d += ONE_DAY
    info = {next_source: next_freq}
    # info = (next_source, next_freq)
    yield next_dt, info

    which can then be used with

    for dt, info in self.some_descriptive_function_name(data):
    # dates should be returned in the same sequence
    # as your original logic
    if info is None:
    do_something_when_no_info(dt)
    else:
    do_something_with_dt_and_info(dt, info)

    If you need to iterate over the data multiple times, you can just do

    tmp = list(self.some_descriptive_function_name(data))
    do_first(tmp)
    do_second(tmp)

    -tkc
     
    Tim Chase, Dec 8, 2013
    #1
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Igor Korot

    Eliminate "extra" variable

    Igor Korot, Dec 6, 2013, in forum: Python
    Replies:
    0
    Views:
    69
    Igor Korot
    Dec 6, 2013
  2. Peter Otten

    Re: Eliminate "extra" variable

    Peter Otten, Dec 8, 2013, in forum: Python
    Replies:
    0
    Views:
    96
    Peter Otten
    Dec 8, 2013
  3. Tim Chase

    Re: Eliminate "extra" variable

    Tim Chase, Dec 8, 2013, in forum: Python
    Replies:
    0
    Views:
    83
    Tim Chase
    Dec 8, 2013
  4. Mark Lawrence

    Re: Eliminate "extra" variable

    Mark Lawrence, Dec 8, 2013, in forum: Python
    Replies:
    14
    Views:
    161
    Igor Korot
    Dec 16, 2013
  5. Tim Chase

    Re: Eliminate "extra" variable

    Tim Chase, Dec 8, 2013, in forum: Python
    Replies:
    0
    Views:
    77
    Tim Chase
    Dec 8, 2013
Loading...

Share This Page