Python 循环浏览以前的类实例结果
这是本书的延续 我有一个B类,它保存一些数据(a和B字段) 我正在将这些数据加载到Criteria类,以便通过Criteria并相应地更改,调用函数Python 循环浏览以前的类实例结果,python,numpy,Python,Numpy,这是本书的延续 我有一个B类,它保存一些数据(a和B字段) 我正在将这些数据加载到Criteria类,以便通过Criteria并相应地更改,调用函数avg,func,calcs 然后,我调用函数p,开始用数据运行程序 守则: import numpy as np class B(): def __init__(self, a,b): self.a = a self.b = b def __repr__(self): return
avg
,func
,calcs
然后,我调用函数p
,开始用数据运行程序
守则:
import numpy as np
class B():
def __init__(self, a,b):
self.a = a
self.b = b
def __repr__(self):
return 'B(%s, %s)'%(self.a, self.b)
class Criteria():
def __init__(self, method, minimum, maximum, measures=None):
self.method = method
self.minimum = minimum
self.maximum = maximum
self.measures = measures
def __repr__(self):
if self.measures is None:
measures = 'measures: None'
else:
measures = [' measures:[']
for m in self.measures:
measures.append(' {}'.format(m))
measures.append(' ]')
measures = '\n'+ '\n'.join(measures)
return 'C({0.method},{0.minimum},{0.maximum}, {1})'.format(self, measures)
def calcs(self):
""" Update the `a` attribute from B class object according to
conditions
"""
if self.measures is not None:
for x in self.measures:
if (x.a > self.minimum and x.a < self.maximum):
x.a = 999
return self.measures
def avg(self, calcs=None):
"""Return the average of values"""
if calcs is None:
calcs = self.measures
if calcs is None:
return 'none'
elif len(calcs)==0:
return '[]'
else:
return np.average([x.a for x in calcs])
def func(self,calcs=None):
"""Return the minimum is input is array or multiple by 1000
if input is a number"""
if calcs is None:
calcs = self.measures
if calcs is None:
return 'none'
#elif len(calcs) == 0:
# return '[]'
else:
if isinstance(calcs, np.ndarray):
return np.amin([x.a for x in calcs])
else:
return calcs*1000
def P(alist):
# use these variables to hold the result of the corresponding execution
# use them in the list loop in order to be able to obtain a result from a `Criteria` evaluation
# and use it as input to the next
last_calcs_values = None
last_calcs_avg = None
last_calcs_m = None
for c in alist:
if c.method=='V':
last_calcs_values = c.calcs()
#print('calcs', last_calcs_values)
yield last_calcs_values
if c.method=='AVG':
if c.measures is None:
last_calcs_avg = c.avg(last_calcs_values)
else:
last_calcs_avg = c.avg()
#print('AVG', last_calcs_avg)
yield last_calcs_avg
if c.method == 'M':
if c.measures is None:
last_calcs_m = c.func(last_calcs_avg)
else:
last_calcs_m = c.func()
#print('M',last_calcs_m)
yield last_calcs_m
我收到:
[B(999, 0.1) B(200, 0.5)]
599.5
599500.0
这是正确的。但是它可以工作,因为p
函数中的代码是硬编码的
所以
1) 我的数据,c1、c2、c3
按顺序使用方法V、AVG、M
因此,在p
函数中,我使用了:
yield last_calcs_values
last_calcs_avg = c.avg(last_calcs_values)
yield last_calcs_avg
last_calcs_m = c.func(last_calcs_avg)
yield last_calcs_m
相同的顺序(硬编码)
我的问题是如何将此代码用于任何顺序。我必须以某种方式检查前一个方法值是什么,并将其放入参数中(而不是放入c.func(last\u calcs\u avg)
2) 在func
中,我已注释掉以下行:
#elif len(calcs) == 0:
# return '[]'
因为如果我运行代码,它会给出:类型为'numpy.float64'的对象没有len()
我尝试了与我稍后在func
中的检查类似的检查:
如果存在(计算,np.ndarray):
但是没有成功
3) 有没有办法只得到最后的结果
因此,不是:
[B(999, 0.1) B(200, 0.5)]
599.5
599500.0
获得:
599500.0
我不明白你说的不硬编码是什么意思
for i in P(alist): pass
print(i)
如果我正确读取
p
,它将保持3个“状态”变量。3个if子句可以按任何顺序调用(我认为可以使用if、ifthen、ifthen、else
语法编写,因为c.method
只匹配一个(对于每个c
)
但列表中对象的顺序将确定值。AVG
对象将使用上一个V
对象设置的值。类似地,M
将使用上一个AVG
。如果首先传递AVG
,它将使用其计算中的初始None
值
因此,V1,AVG,M
序列将使用由V1
设置的B
值
在这个序列中,V1,AVG,V2,M
,M
使用上一个依赖于V1
的AVG
的值
avg
如果其值正由func
使用,则不应返回字符串,或者至少测试必须匹配。[]
是带有len()
零的空列表,但'[]
是带有len
2的2个字符的字符串
类似地,None
是一个唯一的值,您可以使用is None
进行测试,而'None'
是一个4个字符的字符串。我在前面的问题中使用了类似的字符串,只是因为我们正在打印avg
的结果。当时我们没有使用它们进行进一步的计算
如果要确保
AVG
和M
使用上一个V
中的值,需要添加一些逻辑:
lastV, lastA, lastM = None,None,None
if c.method=='V':
lastV = <newV>
lastA, lastM = None,None
elif c.method=='A':
if lastV is None:
error
else:
lastA = <new A based on lastV>
elif c.method=='M':
if lastA is None:
error
<or update lastA>
else:
lastM = <new M based on lastA>
else:
error unknown c.method
在没有len
属性的np.average()
中工作的是什么?len(np.arange(10))
运行,但没有a
属性
In [603]: avg(None,calcs=np.arange(10))
....
<ipython-input-602-48c9f6b255e1> in <listcomp>(.0)
8 else:
9 if hasattr(calcs,'__len__'):
---> 10 return np.average([x.a for x in calcs])
11 else:
12 return np.average(calcs)
AttributeError: 'numpy.int32' object has no attribute 'a'
并且B
对象的列表或数组工作:
In [609]: alist = [B(1,2),B(2,4),B(3,3)]
In [610]: avg(None, alist)
Out[610]: 2.0
In [611]: avg(None, np.array(alist))
Out[611]: 2.0
通过对代码进行硬编码,我按照与输入
V,AVG,M
相同的顺序调用每个函数。当我调用V
时,我会得到一些结果。当我下次调用AVG
时,我希望AVG
方法应用于以前的结果(从V
方法得到的结果)。它们,我想根据我从前面得到的结果调用M
。AVG
。为此,我使用last\u calcs
语句。但正如您所看到的,我在每种情况下都显式调用它们。例如,如果方法是AVG
,则调用c.AVG(last\u calcs\u values)
,但是在调用AVG
之前,我必须找到通过传递最后一个值来获得结果的方法,而不是last\u calcs\u values
。这是唯一的方法?是否有方法存储结果(使用return?)您好,谢谢您的回答。我正在做的检查是正确的吗?我正在检查calcs
可能是数字或数组的情况。嗯。很好!谢谢!(向上投票)。我们可以添加另一个异常除了(AttributeError,TypeError)
In [603]: avg(None,calcs=np.arange(10))
....
<ipython-input-602-48c9f6b255e1> in <listcomp>(.0)
8 else:
9 if hasattr(calcs,'__len__'):
---> 10 return np.average([x.a for x in calcs])
11 else:
12 return np.average(calcs)
AttributeError: 'numpy.int32' object has no attribute 'a'
In [606]: avg(None,calcs=np.arange(10))
Out[606]: 4.5
In [609]: alist = [B(1,2),B(2,4),B(3,3)]
In [610]: avg(None, alist)
Out[610]: 2.0
In [611]: avg(None, np.array(alist))
Out[611]: 2.0