避免 Python 中的冗余循环

Posted

技术标签:

【中文标题】避免 Python 中的冗余循环【英文标题】:Avoid redundant looping in Python 【发布时间】:2019-07-31 17:12:53 【问题描述】:

我有两个列表(项目,销售),对于每对项目,两个列表之间的销售元素我必须调用一个函数。我正在寻找一种pythonic方法来避免这种冗余循环

第一个循环:

# Create item_sales_list

item_sales_list = list()

for item,sales in itertools.product(items,sales):
  if sales > 100:
    item_sales_list.append([item,sales])

result = some_func_1(item_sales_list)

第二次循环:

# Call a function with the result returned from first function (some_func_1)


for item,sales in itertools.product(items,sales):
   some_func_2(item,sales,result)

【问题讨论】:

问题是对第一个循环完成后已知的结果存在依赖性。关于 some_func_2 做什么的任何见解?你能为 some_func_1 制定一个增量解决方案并将其与 some_func_2 相关联吗? 这完全取决于 some_func_2 中如何需要结果。如果需要首先获得完整的结果,那么您无法在一个循环中完成。 您能做的最好的事情就是将第一个 for 循环更改为列表理解。 你甚至不需要理解:item_sales_list = list(product(items, sales)). btw: result = some_func_1(itertools.product(items,sales)) 你可以简化你的第一个循环 【参考方案1】:

如果将结果存储在列表中,至少可以避免第二次调用itertools.product,在some_func_1的调用处添加条件:

item_sales_list = list(itertools.product(items, sales))

result = some_func_1([el for el in item_sales_list if el[1] > 100])

for item, sales in item_sales_list:
    some_func_2(item, sales, result)

除非您可以将不完整版本的result 传递给some_func_2,否则一次传递是不可能的。

【讨论】:

我仍然在做 for 循环,我正在寻找一种最佳解决方案,将所有内容都放在一个循环中。 将 itertools.product 存储在列表中并再次循环是同样的事情。 @min2bro 如果不知道函数的确切逻辑,这是不可能的。这是因为some_func_2 依赖 result,不能在同一个pass上生成。 这里是逻辑: some_func_1 为列表中的每个项目执行一些逻辑并为每个项目创建一个键值对,然后我将结果作为该函数的对象传递给 some_func_2 和它查找每个项目的价值,销售 @min2bro some_func_2 是否需要result 的完整版本,或者只传递result 的不完整版本是否可以?【参考方案2】:

一个解决方案,一个框架挑战。

首先,为了避免多次计算itertools.product(),您可以预先计算一次,然后将其用于两个循环:

item_product = list(itertools.product(items, sales))
item_sales_list = [[item, sales] for item, sales in item_product if sales > 100]

其次,循环两次实际上没有时间劣势(您仍然在做基本相同数量的工作 - 相同的操作,每次相同的次数。所以它仍然属于相同的复杂性等级)。在这种情况下,这是不可避免的,因为您需要第一次计算的结果(这需要遍历整个列表)来进行第二次计算。

result = some_func_1(item_sales_list)
for item, sales in item_product:
    some_func_2(item, sales, result)

如果您可以修改some_func_2() 使其不需要整个 item_sales_list 即可工作,那么您可以将其加载到相同的for 循环中并执行它们一个接一个。在不知道some_func_2() 的工作原理的情况下,不可能提供任何进一步的建议。

【讨论】:

item_product 是一个生成器类型的对象,所以你不应该遍历它两次。 some_func_1 为列表中的每个项目执行一些逻辑并为每个项目创建一个键值对,然后我将结果作为该函数的对象传递给 some_func_2 并查找该值每个项目,销售 @min2bro 如果您可以修改some_func_1()some_func_2() 以处理单个item, sale 对,那么您可以简单地一个接一个地调用它们并将所有内容放入同一个循环中。否则,我认为这是不可能的。 some_func_1 的结果是 item、sale 和 computed_value 的字典,整个结果被传递到 some_func_2 中,它会查找 item 和 sale 的每个值 @min2bro 这就是为什么当你问如何解决问题时,你应该陈述原始问题,而不是你认为的抽象问题。由于您不知道如何解决问题,因此您不知道您遗漏的信息是否相关。

以上是关于避免 Python 中的冗余循环的主要内容,如果未能解决你的问题,请参考以下文章

Python 中的 EWMA 波动性 - 避免循环

如何使用groupby避免python中的循环

怎样删除Oracle数据库中的冗余数据

如何避免 Lambda 架构中的代码冗余?

使用从循环内的代码片段中提取的函数避免代码冗余/计算开销

通用Windows平台(UWP)中的加密/解密存在数据错误(循环冗余校验)