我有一个列表,上面列出了同一个python对象的几个实例,我想遍历这些实例并执行其中的3个方法;但是,在某些情况下,我想选择运行这3个方法中的哪一个(以任意组合)。
我可以这样做:
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检查的项。但是,我可能会多次遍历所有内容,并以这种方式放慢速度。
我很好奇是否有一种简单的方法可以只对检查和循环进行一次评估。我现在得到的东西是这样的:
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...')这确实是可行的,因此循环只执行一次,我认为从技术上讲,每个检查只会被评估一次,但这是大量重复的代码杂乱,如果将第四个方法添加到可能性列表中,将会变得更加令人头疼。那么,有没有另一种更“干净”的写出来的方法,那就是只做一次循环,每次检查只做一次速度?
谢谢!
发布于 2020-01-23 05:39:34
在循环之前,确定每个调用是methodcaller对象还是什么都不做的函数。
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的成本。
发布于 2020-01-23 04:53:35
列出要调用的方法,并遍历该列表。
methods = ['method_1', 'method_2', 'method_3']
for item in list_of_items:
for m in methods:
getattr(item, m)()然后,您可以更改methods的内容以反映这种情况。
发布于 2020-01-23 05:23:34
如果list_of_items中的所有项都具有相同的(已知的)类型,则使用方法列表而不是名称列表的速度会快两倍,实际上与使用ifs的普通循环相同。这对于大量的项可能很重要。
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)输出:
testing plain ifs
0.022666215896606445
testing method names
0.04316902160644531
testing method ptrs
0.021532058715820312注意:只有当所有3个方法都有相同数量的参数时,这才能起作用。一旦参数不同,就可以使用ifs进行初始实现。
https://stackoverflow.com/questions/59867992
复制相似问题