Python堆栈重叠元素累积

时间:2017-01-09 04:01:38

标签: python stack

我想在Python中累积添加Arraystack上的元素

class StockManager:

    __PROFIT = 0

    def __init__(self, o_name, o_surname):
        self.box = ArrayStack()
        self._name = o_name
        self._surname = o_surname

    def buy_shares(self, company, number, buy_price):
        StockManager.__PROFIT -= buy_price * number
        n = 0

        if len(self.box) < 2:
            """there is no overlapped elements when box has no element"""
            self.box.push(company) 
            self.box.push(number)
        else:
            while n < len(self.box):
               if self.box._data[n] == company:
               """every even index(n = 0, 2, 4, ...) refers to company name"""
               """every odd index(n = 1, 3, 5, ...), which is next to even index refers to number of buying"""
                    self.box._data[n + 1] += number
                    n += 2

               elif self.box._data[n] != company:
                    """ if there's no overlapping, then just put the elements """
                    self.box.push(company)
                    self.box.push(number)
                    n += 2
        return print(self.box._data)

和类Arraystack是这样的:

class ArrayStack:
    """LIFO Stack implementation using a Python list as underlying storage."""

    def __init__(self):
        """Create an empty stack."""
        self._data = []                       # nonpublic list instance

    def __len__(self):
        """Return the number of elements in the stack."""
        return len(self._data)

    def is_empty(self):
        """Return True if the stack is empty."""
        return len(self._data) == 0

    def push(self, e):
        """Add element e to the top of the stack."""
        self._data.append(e)                  # new item stored at end of list

    def top(self):
        """Return (but do not remove) the element at the top of the stack.

        Raise Empty exception if the stack is empty.
        """
        if self.is_empty():
            raise AssertionError('Stack is empty')
        return self._data[-1]                 # the last item in the list

    def pop(self):
        """Remove and return the element from the top of the stack (i.e., LIFO).

        Raise Empty exception if the stack is empty.
        """
        if self.is_empty():
            raise AssertionError('Stack is empty')
        return self._data.pop()               # remove last item from list

    def print_contents(self):
        print("Stack content: {0}".format(self._data))

当我用

运行stockmanager时
if __name__ == '__main__':
    P = StockManager("A","B")
    P.buy_shares("hyundai", 20, 100)
    P.buy_shares("hyundai", 20, 100)
    P.buy_shares("hyundai", 20, 100)
    P.buy_shares("lg", 20, 100)

结果是

['hyundai', 20]  => O.K
['hyundai', 40]  => O.K
['hyundai', 60]  => O.K
['hyundai', 60, 'lg', 40] => It should be ['hyundai', 60, 'lg', 20]
['hyundai', 60, 'lg', 60, 'lg', 40] => don't know why this result comes...

我该如何处理这个问题?

2 个答案:

答案 0 :(得分:1)

所以,问题在于你的while循环:

           while n < len(self.box):
           if self.box._data[n] == company:
               """every even index(n = 0, 2, 4, ...) refers to company name"""
               """every odd index(n = 1, 3, 5, ...), which is next to even index refers to number of buying"""
               self.box._data[n + 1] += number
               n += 2

           elif self.box._data[n] != company:
               """ if there's no overlapping, then just put the elements """
               self.box.push(company)
               self.box.push(number)
               n += 2

想象一下,我们已经开始了:

P = StockManager("A","B")
P.buy_shares("hyundai", 20, 100)
P.buy_shares("hyundai", 20, 100)
P.buy_shares("hyundai", 20, 100)

到目前为止,一切都按计划进行。现在,你试试:

P.buy_shares("lg", 20, 100)

所以:n == 0len(self.box) == 2,所以我们进入循环。

if条件失败,self.box._data[n] != 'lg',所以我们转到elif区块:

           self.box.push(company)
           self.box.push(number)
           n += 2

现在,box == ['hyundai', 60, 'lg', 20]n == 2。可是等等!循环条件是n < len(box),但是len(box) == 4,所以我们再次进入while循环!这一次,if条件从self.box._data[2] == 'lg'开始经过 self.box._data[n + 1] += number n += 2

所以你执行if-block的主体:

n == 4

现在,box == ['hyundai', 60, 'lg', 40]4 < len(box)。这一次,offset = 0 i = -2 for i in range(0, len(self.box), 2): if self.box._data[n] == company: break else: offset = 2 self.box.push(company) self.box.push(0) self.box._data[i + offset + 1] += number 失败,我们退出循环,你的功能结束了。

现在,堆栈对我来说似乎是错误的数据结构。不得不将尺寸增加两倍,这很笨重。如果真的想要这样做,我建议采用类似

的方法
dict

但同样,这很笨重。你最好使用self.box[company] = self.box.get(company, 0) + 1 框,然后逻辑可以简单地实现:

defaultdict

或者更好的是,使用>>> from collections import defaultdict >>> box = defaultdict(int) >>> box defaultdict(<class 'int'>, {}) >>> box['lg'] += 20 >>> box defaultdict(<class 'int'>, {'lg': 20}) >>> box['lg'] += 20 >>> box defaultdict(<class 'int'>, {'lg': 40}) >>> box['lg'] 40

const deferred = $q.defer();
deferred.promise.finally(() => {});
deferred.reject();

答案 1 :(得分:0)

您正在使用索引迭代整个列表;如果第一个company / number与您购买的股票不匹配,则会自动附加到列表的末尾;然后下一组索引将指向刚刚附加的 new 公司,因此它会添加数字。 elif不正确 - 您不应该添加新的company / number对,直到您遍历整个列表并且找不到它为止。

这就是你在做什么

>>> a = ['a',1]
>>> n = 0
>>> comp, nbr = 'b', 2
>>> while n < len(a):
....    if a[n] == comp:
            print('comp found at', n) 
            a[n+1] += nbr
            n += 2
        else:
            print('n =', n, 'appending', comp) 
            a.append(comp)
            a.append(nbr)
            n += 2


n = 0 appending b
comp found at 2
>>>

您可以采取以下措施来解决问题:

>>> a = ['a',1]
>>> n = 0
>>> comp, nbr = 'b', 2
>>> while n < len(a):
        found = False
        if a[n] == comp:
            print('comp found at', n) 
            a[n+1] += nbr
            found = True
        n += 2


>>> if not found:
        a.append(comp)
        a.append(nbr)


>>> a
['a', 1, 'b', 2]
>>>

但正如评论中所建议的那样,您最好将购买存储在字典中。