I'm writing a stack class MyStack
, implemented as a list, where each element is a dictionary with two fields ('a'
and 'b'
). Each of these dictionary fields is itself a list (initialized as empty lists in push()
). Apart from push()
and pop()
(the latter skipped for readability here) I intend to add
elements to these lists (the dictionary fields) for the element at the top of the stack (index [-1]
).
The problem is the value gets added to both dictionary fields, not just the selected one. However, I then test this with a standalone variable,standalone_stack
,that I test is identical to the stack
variable of object MyStack
. Surprisingly, I get what I want - I append only to the selected field. Here's the code:
class MyStack(object):
def __init__(self):
self.stack = []
def push(self):
self.stack.append(dict.fromkeys(['a', 'b'], []))
def add(self, field, value):
self.stack[-1][field].append(value)
def __str__(self):
return str(self.stack)
def lists_the_same(list1, list2):
if list1 == list2:
print 'Yes, the same'
else:
print 'No, not the same'
# Create essentially the same data in two different ways:
ms = MyStack()
standalone_stack = [{'a': [], 'b': []}]
ms.push()
print ms
print standalone_stack
lists_the_same(ms.stack, standalone_stack)
# Now modify both:
field = 'a'
value = 2
ms.add(field=field, value=value)
standalone_stack[-1][field].append(value)
print ms
print standalone_stack
lists_the_same(ms.stack, standalone_stack)
My output with Python 2.7.6 is below:
[{'a': [], 'b': []}]
[{'a': [], 'b': []}]
Yes, the same
[{'a': [2], 'b': [2]}]
[{'a': [2], 'b': []}]
No, not the same
What I need help with is:
- Why there's this odd difference in behavior when the same list is a field of an object (
self.stack
) or a standalone variablestandalone_stack
? Even pointing out Python related keywords would help, since I'm not able to google this out for some time already. - If I could make my question more clear. This is my first post here.
- Maybe I'm thinking about this backwards and you'd implement this differently, possibly in a more Pythonic way.