简体   繁体   English

将一个函数列表应用于列表中的每个项目?

[英]Apply a list of functions to every item in a list?

I am making a program that works on chat files under the following general form: 我正在制作一个程序,该程序适用于以下一般形式的聊天文件:

  1. Open file & import lines (via readlines ) 打开文件和导入行(通过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 标记哪些行是/me命令
  3. Do a second pass over the list of dicts to apply various manipulations on them, such as: 对dicts列表进行第二次传递以对它们应用各种操作,例如:
    • Replacing every mention of a nick with its alias 用别名替换每一个缺口
    • Applying special formatting to /me commands /me命令应用特殊格式

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. 不是在配置文件中有多个开关,而是在循环中有很多if语句检查,我相信如果我在其他地方生成函数列表然后向程序提供dicts(或字符串列表,取决于哪个),程序会更清晰。我所在的程序的一部分)和一系列函数,以便将函数列表应用于对象列表中的每个项目。

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. 然而,上面并没有消除的需要if对所有的交换机检查,将不允许赋予功能a在两个不同的地方,除非我明确地添加交换机这样做。

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. 让每个func处理数据,使循环更像管道。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM