4

I have a dictionary of lists which contain certain values. How do I update a value in a list without affecting values at same position of other keys?

my code:

open = []
high = []
low = []
close = []  

ohlc_list = {}

for i in range(0,20):
   open.append(0)
   close.append(0)
   high.append(0)
   low.append(0)


for x in range(0,5):
   ohlc_list[x] = [open,high,low,close] 

ohlc_list[1][1][3] = 0  

This changes the 4th (3+1) element of list high(1) of all the keys rather than changing it for just key 1 .

I want to change the value of a list related to a specific key only. How do I do that?

  • `open,high,low,close` are names for datastructures - they point to the exact same data. You add this reference 5 times. If you change the data behind one reference all other references point to the same data and you see "same" changes. Your error is that you added the same references over and over to begin with. – Patrick Artner Oct 08 '18 at 11:08

2 Answers2

3
for x in range(0, 5):
   ohlc_list[x] = [open , high , low, close]

This does not do what you think it does. It creates 5 references to the same 4 lists and keep these references under different keys.

This can be shown with this loop:

for value in ohlc_list.values():
    print([id(inner_list) for inner_list in value])

# [2446702057416, 2446702057544, 2446692440648, 2446702057480]
# [2446702057416, 2446702057544, 2446692440648, 2446702057480]
# [2446702057416, 2446702057544, 2446692440648, 2446702057480]
# [2446702057416, 2446702057544, 2446692440648, 2446702057480]
# [2446702057416, 2446702057544, 2446692440648, 2446702057480]

We see that all inner lists have the same id, which mean they all reference the same place in memory (overly simplified on purpose).

What you want is 5 copies of these lists. You can either use an empty slice ([:]) or copy to achieve this:

for x in range(0, 5):
   ohlc_list[x] = [open[:], high[:], low[:], close[:]] 

If we print all the ids of the inner lists again, we see that now we actually got different lists in memory:

# [2592165177544, 2592165177480, 2592165177416, 2592165177352]
# [2592165177672, 2592165177736, 2592165177800, 2592165177864]
# [2592165177992, 2592165178056, 2592165178120, 2592165178184]
# [2592165178312, 2592165178376, 2592165178440, 2592165178504]
# [2592165178632, 2592165178696, 2592165178760, 2592165178824]
DeepSpace
  • 78,697
  • 11
  • 109
  • 154
1

you need to copy the lists

from copy import copy

and then in your loop:

ohlc_list[x] = [copy(open), copy(high), copy(low), copy(close)]

otherwise you're just adding the same list object to all of the entries.

nullp0tr
  • 485
  • 3
  • 11