在Python循环中跟踪结果的最佳方法
我有一个比较大的循环,需要运行500次,而我对这个编程语言和这种模拟还不太熟悉。
不过,我需要记录每次运行的结果,看看列表(table1)里面是否全是0,全是1,或者是两者的混合。
我只是想知道,什么方法最快能找出这500次模拟中,有多少次的结果是全0、全1或者混合的,另外,使用追加(append)操作会不会让速度变得太慢。
for x in range(0, 500):
times = 300
gamma_val = 2
table1 = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
total = 0.0
while total < times:
table = [0 for i in range (21)]
for d1 in range(21):
if table1[d1]:
table[d1] = -(1/gamma_val)*math.log((random.random()))
else:
table[d1] = -(math.log(random.random()))
####Goes on to make new table1 with changes, either all 1's, all 0's or a mix of 0s #########and 1s
files1 = 0
files01 = 0
files0 = 0
if "1" "0" in table1 == True:
files01 += 1
elif 1 in table == True:
files1 += 1
elif 0 in table1 == true:
files0 += 1
3 个回答
使用append()
这个方法时,速度损失并不比多次扫描数据要大。而且,相比于计算,内存操作所耗费的时间也很少。所以不用太担心这个问题。如果我能通过你想要累积的列表的长度来获取计数,那我可能就不需要单独保存计数了。一次性处理所有事情会更清晰。先把东西做出来,然后再计数。
我相信标准容器在算法速度方面的表现。所以我会把这一行数据转换成一个集合(Set),然后和Set([0])、Set([1])、Set([0,1])进行比较。我认为使用'in'会对这一行数据进行两次扫描,而Set()只需要一次。
BOTH = set([0, 1])
results = {'0': [], '1': [], '01': []}
.... make the list ....
elements = set(table)
if elements == BOTH:
results['01'].append(table)
else if 1 in elements:
results['1'].append(table)
else:
results['0'].append(table)
我会尽量在风格上做出选择,而不是直接指出错误:
使用最后的else,不要把所有条件都列出来;这样会更易读。把所有条件都列出会让读者想知道还有什么情况没考虑到,这样会让人感到不安。
一般来说,直接把东西和True或False进行比较并不是Python的风格。在Python中,检查是否等于常量True是获取条件结果的最不可靠的方法。Python中有很多习惯用法是依赖于某个对象的存在或列表不为空来表示一个语句的真假。所以你会遇到一些程序员在辅助函数中返回除了True或False以外的值来表示布尔判断。习惯一下吧,不要太挑剔。
另外,虽然这听起来很痛苦,但in和其他比较运算符混合使用时,可能会让人误解为<,这对于非分析师来说是非常不符合习惯的,所以你绝对不应该这样做。
你最后到底需要什么呢?
如果你只是想知道所有1的比例、所有0的比例,或者它们的混合比例,我觉得直接增加变量的值会更直观,而不是生成列表。如果你把代码设置成这样:
...
files1=0
files01=0
files0=0
if 1 in table1 and 0 in table1:
files01 += 1
elif 1 in table:
files1 += 1
elif 0 in table1:
files0 += 1
...
那么你就不需要在最后用 len(files01)
来知道有多少个是混合了1和0的了。
在选择要添加的位置之前,先创建两个布尔变量(Has1s 和 Has0s),在 while 循环之前把它们都设置为 False。当你遇到 1 的时候,把 Has1s 设置为 True;遇到 0 的时候,把 Has0s 设置为 True。这样做可以避免在最后进行多达 3 次的搜索。