1

I am making a program that works on chat files under the following general form:

  1. Open file & import lines (via readlines)
  2. Do an initial pass to turn the list of strings into better-formed data (currently dicts) by:
    • Throwing out out malformed lines
    • Separating out the usernames from the text of the message
    • Throwing out lines for ignored (typically bot) users
    • Marking which lines are /me commands
  3. Do a second pass over the list of dicts to apply various manipulations on them, such as:
    • Replacing every mention of a nick with its alias
    • Applying special formatting to /me commands

Rather than have multiple switches in the config file and lots of if statement checks within the loops, I believe the program would be cleaner if I generated the list of functions elsewhere and then fed the program the list of dicts (or strings, depending on which part of the program I'm at) and a list of functions such that the list of functions gets applied to each of the items in the list of objects.

It seems that this probably would be a good case for list comprehensions if I were only applying a single function to each item, but I don't want to have to do a separate pass through the log for every function that I want to call. However, this answer notes that list comprehension probably aren't what I want, since they return a completely new list, rather than modifying in place.


Is my best option to have two variants of the following?

for item in list:
    item = a(b(c(d(item, dparam1, dparam2), cparam)), aparams)

(for readability, I'd put each function on its own line, like:

for item in list:
    item = d(item, dparam1, dparam2)
    item = c(item, cparam)
    item = b(item)
    item = a(item, aparams)

However, the above doesn't eliminate the need for if checks on all the switches and wouldn't allow for applying function a at two different places unless I explicitly add a switch to do so.

Community
  • 1
  • 1
cjm
  • 451
  • 4
  • 20
  • 1
    Can you provide some sample input and output as part of a [mcve]? I don't see any immediate warning signs in your current code - wrapper functions are perfectly normal in cases like this. Also, a comprehension can replace all the items of an existing list rather than creating a separate list object with e.g. `L[:] = [f(i) for i in L]`. – TigerhawkT3 Mar 30 '17 at 04:57

1 Answers1

0

Based on your sample code, you may try this way,

func_list = [d, c, b, a]
for idx, item in enumerate(item_list):
    item_list[idx] = reduce(lambda v, func: func(v), func_list, item)

Let each func handle the data, make the loop more like pipeline.

Qiang Jin
  • 4,427
  • 19
  • 16
  • It's generally clearer to use a loop rather than `reduce` (which is why it was relegated to `functools`): `for f in func_list: item_list[idx] = f(item_list[idx])`. – TigerhawkT3 Mar 30 '17 at 06:36