首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >有没有可能简化循环和多个if语句的速度检查?

有没有可能简化循环和多个if语句的速度检查?
EN

Stack Overflow用户
提问于 2020-01-23 04:47:32
回答 3查看 80关注 0票数 0

我有一个列表,上面列出了同一个python对象的几个实例,我想遍历这些实例并执行其中的3个方法;但是,在某些情况下,我想选择运行这3个方法中的哪一个(以任意组合)。

我可以这样做:

代码语言:javascript
运行
复制
do_method_1 = True
do_method_2 = True
do_method_3 = True

for item in list_of_items:
    if do_method_1:
        item.method_1()
    if do_method_2:
        item.method_2()
    if do_method_2:
        item.method_2()

它很容易读懂,但是,我对循环中的每一项都做了多次检查,并稍微放慢了速度。我还可以通过执行每个检查来翻转它,然后循环执行每个True/False检查的项。但是,我可能会多次遍历所有内容,并以这种方式放慢速度。

我很好奇是否有一种简单的方法可以只对检查和循环进行一次评估。我现在得到的东西是这样的:

代码语言:javascript
运行
复制
do_method_1 = True
do_method_2 = True
do_method_3 = True

if do_method_1:
    if do_method_2:
        if do_method_3:
            for item in list_of_items:
                item.method_1()
                item.method_2()
                item.method_3()
        else:
            for item in list_of_items:
                item.method_1()
                item.method_2()
    elif do_method_3:
        for item in list_of_items:
            item.method_1()
            item.method_3()
    else:
        for item in list_of_items:
            item.method_1()
else:
    if do_method_2:
        if do_method_3:
            for item in list_of_items:
                item.method_2()
                item.method_3()
        else:
            for item in list_of_items:
                item.method_2()
    elif do_method_3:
        for item in list_of_items:
            item.method_3()
    else:
        print('not doing anything...')

这确实是可行的,因此循环只执行一次,我认为从技术上讲,每个检查只会被评估一次,但这是大量重复的代码杂乱,如果将第四个方法添加到可能性列表中,将会变得更加令人头疼。那么,有没有另一种更“干净”的写出来的方法,那就是只做一次循环,每次检查只做一次速度?

谢谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-01-23 05:39:34

在循环之前,确定每个调用是methodcaller对象还是什么都不做的函数。

代码语言:javascript
运行
复制
from operator import methodcaller

def noop(obj):
    pass

do_method_1 = True
do_method_2 = True
do_method_3 = True

m1 = methodcaller('method_1') if do_method_1 else noop
m2 = methodcaller('method_2') if do_method_2 else noop
m3 = methodcaller('method_3') if do_method_3 else noop    


for item in list_of_items:
    m1(item)
    m2(item)
    m3(item)

Barmar's answer类似,您可以创建要使用的methodcaller对象列表并对其进行迭代,从而消除调用noop的成本。

票数 1
EN

Stack Overflow用户

发布于 2020-01-23 04:53:35

列出要调用的方法,并遍历该列表。

代码语言:javascript
运行
复制
methods = ['method_1', 'method_2', 'method_3']
for item in list_of_items:
    for m in methods:
        getattr(item, m)()

然后,您可以更改methods的内容以反映这种情况。

请参阅Call a Python method by name

票数 1
EN

Stack Overflow用户

发布于 2020-01-23 05:23:34

如果list_of_items中的所有项都具有相同的(已知的)类型,则使用方法列表而不是名称列表的速度会快两倍,实际上与使用ifs的普通循环相同。这对于大量的项可能很重要。

代码语言:javascript
运行
复制
import time

class Item:
    def method_1(self):
        pass
    def method_2(self):
        pass
    def method_3(self):
        pass

list_of_items = []  
for i in range(100000):
    list_of_items.append(Item())

do_method_1 = True
do_method_2 = True
do_method_3 = True

def test1():
    for item in list_of_items:
        if do_method_1: item.method_1()
        if do_method_2: item.method_2()
        if do_method_2: item.method_2()

def test2():
    methods = []
    if do_method_1: methods.append('method_1')
    if do_method_2: methods.append('method_2')
    if do_method_3: methods.append('method_3')

    for item in list_of_items:
        for m in methods:
            getattr(item, m)()

def test3():
    methods = []
    if do_method_1: methods.append(Item.method_1)
    if do_method_2: methods.append(Item.method_2)
    if do_method_3: methods.append(Item.method_3)

    for item in list_of_items:
        for m in methods:
            m(item)

print('testing plain ifs')
start = time.time()
test1()
print(time.time() - start)

print('testing method names')
start = time.time()
test2()
print(time.time() - start)

print('testing method ptrs')
start = time.time()
test3()
print(time.time() - start)

输出:

代码语言:javascript
运行
复制
testing plain ifs
0.022666215896606445
testing method names
0.04316902160644531
testing method ptrs
0.021532058715820312

注意:只有当所有3个方法都有相同数量的参数时,这才能起作用。一旦参数不同,就可以使用ifs进行初始实现。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59867992

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档