0

I have the following code:

class Stock(object):
     def __init__(self,name,price):
         self.name = name
         self.price = price

     def Add_Price(self,data):
          self.price.append(data)

def test():
     l=[]
     n=0
     while n < 390:
         s1= Stock('A', l)
         s2= Stock('B', l)

         s1.Add_Price(d1[n])  # d1 is a list with the prices for A #
         s2.Add_Price(d2[n])  # d2 is a list with the prices for B #

         print s1.price, s2.price

         n=n+1

When I run it I would have assume that calling s1.price you would receive an array with the price of stock A and that s2.price would have the price of stock B. However when I run it, s1.price and s2.price are identical.

So it seems that when I append a new value to self.price, it is not appending it to a variable of the current instance of the class.

Can anyone please point out what I'm doing wrong?

Edit:

Current output :

[10 150] [10 150]
[10 150 10.2 150.3] [10 150 10.2 150.3]

Desired output :

[10] [150]
[10 10.3] [ 150 150.3]
martineau
  • 119,623
  • 25
  • 170
  • 301
Mustard Tiger
  • 3,520
  • 8
  • 43
  • 68

1 Answers1

1

You're passing a reference of the same list to both instances. A list is a mutable object, so it's pass-by-reference.

One solution is to create two lists:

def test():
    l_1 = []
    l_2 = []
    s1= Stock('A', l_1)
    s2= Stock('B', l_2)
    n=0   

    while n < 390:
        s1.Add_Price(d1[n])  # d1 is a list with the prices for A # 
        s2.Add_Price(d2[n])  # d2 is a list with the prices for B #

However, you will also be appending to l_1 and l_2 externally to the class, due to the fact it shares the same reference. Since d1 and d2 are lists of prices, another solution would be to create a list on instantiation and extend the Stock's list if Add_Price() is passed a list, and to append a price if it's not a list.

Stock class constructor:

class Stock(object):

    def __init__(self,name,prices=None):
        self.name = name
        self.price = prices or [] #create a new list on instantiation

    def Add_Price(self,data):
        if isinstance(data, list):
            self.prices.extend(data)
        else:
            self.prices.append(data)

Then in your test() function:

def test():
    s1 = Stock('A')
    s2 = Stock('B')

    s1.Add_Price(d1[:390])
    s2.Add_Price(d2[:390])

The d1[:390] is splicing, which represents all elements from index 0 (inclusive) to index 390 (exclusive), which allows you to remove the need for the while loop.

the_constant
  • 681
  • 4
  • 11
  • Thanks I should have probably mentioned that the loop is there for other reasons... but the first part of the answer solved the issue – Mustard Tiger Jan 18 '17 at 02:27
  • @abcla I edited my post. You still can use the performance benefits of splicing if you aren't using that specific n element anywhere else in the while loop, however yes, if you're using the element elsewhere, you may wish to append individually based on your circumstance. Also, if this is the correct answer, please accept it :) – the_constant Jan 18 '17 at 02:34