0

In my case, I have a dictionary like this

dic_ = {'btcusd': [-1.0, -1.0],
        'usdjpy': [-1.0, -1.0]}

For example, I would like to update the key 'usdjpy', I using this code

dic_['usdjpy'].append(1)

However, It updates all other keys in this dictionary and gives the result like

{'btcusd': [-1.0, -1.0, 1],
 'usdjpy': [-1.0, -1.0, 1]}

So how to solve this problem?

My desire result is as below

{'btcusd': [-1.0, -1.0],
 'usdjpy': [-1.0, -1.0, 1]}
ShanN
  • 831
  • 1
  • 9
  • 20
  • 1
    How have you created the dict? – yatu Jun 15 '20 at 09:32
  • Due to I need to generate many dicts which have same format so I create the function by dict_ = dict(zip(symbol_list, [list()]*len(symbol_list))) – ShanN Jun 15 '20 at 09:40
  • 1
    Probably dupe of https://stackoverflow.com/questions/240178/list-of-lists-changes-reflected-across-sublists-unexpectedly – yatu Jun 15 '20 at 09:41

3 Answers3

1

The issue is during the initialization of your dictionary. Do check, the id's for both the list are same. i.e. the memory in which both the list are is same.

> id('btcusd') == id('usdjpy')
True

To replicate this issue, Here I have initialized the an list for a,b

> list = ['a','b']
> dic_ = dict.fromkeys(list, [-1.0,1.0])
> dic_['a'] is dic['b']
True

You can use list comprehension for sorting the issue

> dic_ = {key: [-1.0,1.0] for key in list}
> dic_['a'] is dic_['b']
False

Just in your case, the issue is your initialization:

dict_ = dict(zip(symbol_list, [list()]*len(symbol_list)))

Just for a demo on [list()]*len(symbol_list),

> l = [['a']]*3
[['a'], ['a'], ['a']]
> for i in l:
>    print(id(i), end=' : ')
139970284317824 : 139970284317824 : 139970284317824
PaxPrz
  • 1,778
  • 1
  • 13
  • 29
1

The root of this problem comes from the way I define the dictionary. Like @yatu comment under my post. For example, If I generate the dictionary like this

symbol_list = ['a', 'b, 'c', 'd']
dict_ = dict(zip(symbol_list, [list()]*len(symbol_list)))

Then append using normal .append() method. It will append for all value-list in this dict_

But if creating the dict_ in another way like

symbol_list = ['a', 'b', 'c', 'd']
dict_ = {}
for x in range(0, len(symbol_list)):
    dict_[symbol_list[x]]= list()

then the append() method will work as desired

The reason is answered in detail in this post: List of lists changes reflected across sublists unexpectedly

ShanN
  • 831
  • 1
  • 9
  • 20
0

there must be something else that you're doing to get this result. I tried it and it works just fine

dic_ = {'btcusd': [-1.0, -1.0],
        'usdjpy': [-1.0, -1.0]}
dic_['usdjpy'].append(1)
print(dic_)

output

{'btcusd': [-1.0, -1.0], 'usdjpy': [-1.0, -1.0, 1]}
Qdr
  • 703
  • 5
  • 13