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