When running below code, the dict shows unexpected behaviour
I a nutshell, I select a date in the past and add the information to a dict about that date. All is well until I print the resulting dict after all the iterations:
functioning code, you can C/V this into your shell and run it with dictTester():
from calendar import datetime as calendar_date
from datetime import datetime
def dictTester():
breakdowns_dict = {}
for row in range(2):
temp_list = [row, None, None]
while_true_counter = 0
date_extracted = datetime.now() - calendar_date.timedelta(days=row)
date_extracted = datetime.strptime(date_extracted.strftime('%Y-%m-%d'),'%Y-%m-%d')
date_now = datetime.strptime(datetime.now().strftime('%Y-%m-%d'),'%Y-%m-%d')
while True:
if date_extracted > date_now:
print('date > now')
print('break')
break
if date_extracted == date_now:
print('date == now')
temp_list[1] = date_extracted.strftime('%Y-%m-%d')
if while_true_counter > 0:
temp_list[2] = 'RIGHT'
else:
temp_list[2] = 'PURE'
print(temp_list)
if date_extracted < date_now:
print('date < now')
temp_list[1] = date_extracted.strftime('%Y-%m-%d')
if while_true_counter > 0:
temp_list[2] = 'MIDDLE'
else:
temp_list[2] = 'LEFT'
print(temp_list)
if date_extracted not in breakdowns_dict:
breakdowns_dict[date_extracted] = {}
print('created entry')
else:
print('updated entry')
print(date_extracted)
print(len(breakdowns_dict[date_extracted]))
breakdowns_dict[date_extracted][len(breakdowns_dict[date_extracted])] = temp_list
print(breakdowns_dict[date_extracted][len(breakdowns_dict[date_extracted])-1])
# next iteration
date_extracted += calendar_date.timedelta(days=1)
while_true_counter += 1
for bd_date in breakdowns_dict:
for bd_entry in breakdowns_dict[bd_date]:
print(bd_date.strftime('%Y-%m-%d'), breakdowns_dict[bd_date][bd_entry])
python shell output
$ date == now
$ [0, '2021-03-18', 'PURE']
$ created entry '2021-03-18' 0 = [0, '2021-03-18', 'PURE']
$ date > now
$ break
$ date < now
$ created entry 2021-03-17 0 = [1, '2021-03-17', 'LEFT']
$ date == now
$ updated entry '2021-03-18' 1 = [1,'2021-03-18', 'RIGHT']
$ date > now break
So you would expect the result dict to be:
$ '2021-03-18' 0 = [0, '2021-03-18', 'PURE']
$ '2021-03-18' 1 = [1,'2021-03-18', 'RIGHT']
$ '2021-03-17' 0 = [1, '2021-03-17', 'LEFT']
But instead it prints:
$ '2021-03-18' [0, '2021-03-18', 'PURE']
$ '2021-03-18' [1, '2021-03-18', 'RIGHT']
$ '2021-03-17' [1, '2021-03-18', 'RIGHT']
and you can see more of this funky behaviour when increasing the row value
for 3 you should get a ‘PURE’ a ‘LEFT’-‘RIGHT’ and a ‘LEFT’-‘MIDDLE’-‘RIGHT’ and so on, you get the idea
but that would be disregarding the adversary.
Advertisement
Answer
The simple bug was a pass by reference vs pass by value error, silly me
as answered here: python list by value not by reference
updating the code line:
breakdowns_dict[date_extracted][len(breakdowns_dict[date_extracted])] = temp_list
to
breakdowns_dict[date_extracted][len(breakdowns_dict[date_extracted])] = temp_list[:]
was all that was required