我想在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...
我该如何处理这个问题?
答案 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 == 0
和len(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]
>>>
但正如评论中所建议的那样,您最好将购买存储在字典中。