Python 循环浏览以前的类实例结果

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

这是本书的延续

我有一个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 '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