Python 字典更新-非常奇怪的行为

Python 字典更新-非常奇怪的行为,python,Python,在代码下运行时,dict显示意外行为 简而言之,我选择过去的一个日期,并将该日期的信息添加到dict中。 在我在所有迭代之后打印生成的dict之前,一切都很顺利: 功能代码,您可以将其C/V到shell中,并使用dictTester运行它: from calendar import datetime as calendar_date from datetime import datetime def dictTester(): breakdowns_dict = {} for r

在代码下运行时,dict显示意外行为

简而言之,我选择过去的一个日期,并将该日期的信息添加到dict中。 在我在所有迭代之后打印生成的dict之前,一切都很顺利:

功能代码,您可以将其C/V到shell中,并使用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 itteration
            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])
但它却打印:

$ '2021-03-18' [0, '2021-03-18', 'PURE'] 
$ '2021-03-18' [1, '2021-03-18', 'RIGHT'] 
$ '2021-03-17' [1, '2021-03-18', 'RIGHT'] 
当增加行值时,您可以看到更多这种古怪的行为

对于3,你应该得到一个‘纯’的‘左’-‘右’和一个‘左’-‘中’-‘右’等等,你明白了

但这就是无视对手。

简单的错误是“通过引用传递”与“通过值传递”的错误,愚蠢的我

正如这里所回答的:

更新代码行:

breakdowns_dict[date_extracted][len(breakdowns_dict[date_extracted])] = temp_list


这就是所需的全部

看起来您在该循环中重复地将同一个临时列表对象存储在数据结构中。如果您没有意识到这会是一个问题,您可能想阅读post代码,这是很好的,但是您还需要发布驱动它的代码,这样我们就有了一个自包含的测试用例。@hewi附加到dict中不会复制临时列表。您正在将同一个列表存储在多个dict条目中。@hewi否。Python既不使用按引用传递,也不使用按值传递。@hewi:列表不是这样工作的。您没有收到错误,因为您使用了dict而不是列表,但对连续整数索引使用dict是一个有问题的决定。使用list和list.append更有意义。你完全错了。赋值在这两种情况下都具有引用语义。[:]是一个切片,用于创建副本。它仍然具有引用语义。python不使用按引用传递或按值传递。不管赋值是否始终具有引用语义。
$ '2021-03-18' [0, '2021-03-18', 'PURE'] 
$ '2021-03-18' [1, '2021-03-18', 'RIGHT'] 
$ '2021-03-17' [1, '2021-03-18', 'RIGHT'] 
breakdowns_dict[date_extracted][len(breakdowns_dict[date_extracted])] = temp_list
breakdowns_dict[date_extracted][len(breakdowns_dict[date_extracted])] = temp_list[:]