Python堆栈重叠元素累积

Python堆栈重叠元素累积,python,stack,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, bu

我想在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)
当我和你一起管理股票经理的时候

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...

如何处理此问题?

因此,问题在于您的
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.buy_shares("lg", 20, 100)
所以:
n==0
len(self.box)==2
,所以我们进入循环

如果
条件失败,
self.box.\u data[n]!='lg'
,因此我们转到
elif
块:

           self.box.push(company)
           self.box.push(number)
           n += 2
现在,
box==['hyundai',60',lg',20]
n==2
。但是等等!循环条件是
n
,但是
len(box)==4
,所以我们再次进入while循环!这一次,由于
self.box.\u data[2]=“lg”
,因此
if
条件在这一次通过

因此,执行if块的主体:

           self.box._data[n + 1] += number
           n += 2
现在,
n==4
box==['hyundai',60',lg',40]
。这次,
4
失败,我们退出循环,您的函数结束

现在,堆栈在我看来似乎是错误的数据结构。必须把尺寸增加两倍是很笨重的。如果你真的想这样做,我会建议一种方法,比如

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
for box,然后逻辑可以简单地实现为:

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
>>从集合导入defaultdict
>>>box=defaultdict(int)
>>>盒子
defaultdict(,{})
>>>盒子['lg']+=20
>>>盒子
defaultdict(,{'lg':20})
>>>盒子['lg']+=20
>>>盒子
defaultdict(,{'lg':40})
>>>方框['lg']
40

您正在使用索引对整个列表进行迭代;如果第一个
公司
/
编号
与您正在购买的股票不匹配,它将自动附加到列表的末尾;然后,下一组索引将指向刚刚添加的新公司,以便添加数字。
elif
不正确-在遍历整个列表并且没有找到它之前,您不应该附加新的
公司
/
编号

这就是你正在做的

>>> 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 >>>公司,nbr='b',2 >>>当n>>
这是您可以做的修复方法:

>>> 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]
>>>
a=['a',1] >>>n=0 >>>公司,nbr='b',2 >>>当n>>如果未找到: a、 附加(comp) a、 附加(nbr) >>>a [a',1',b',2] >>>


但正如评论中所建议的,您可能最好将购买的内容存储在字典中。

您在
购买股票
中的while循环究竟想实现什么?另外,为什么要使用堆栈?为什么不用字典呢?啊,因为它是用来练习数据结构-堆栈-所以我制作并使用堆栈而不是字典。我还认为字典的效率要高得多。我认为“for I(0,len(self.box),2):”在Python3中犯了一个语法错误。5@S.JHahn我把它复制过来是个错误。对于范围(0,len(self.box),2)中的i,它应该为
>>> 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]
>>>