You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何近乎相同的Python代码执行后freq变量结果差异巨大?

top1与top2函数freq输出差异的原因分析

问题描述

我需要验证合理性:top1与top2函数代码近乎一致,但执行后freq变量的输出内容却存在显著差异。请问原因是什么?我忽略了哪些细节?

代码与执行输出

测试代码

def top1(nums, k):
    count = {}
    
    for i in nums:
        if i not in count:
            count[i] = 1
        else:
            count[i] += 1
    
    freq = (len(nums) + 1) * [[]]

    print('count', count)
    print('freq', freq)
    for n, c in count.items():
        freq[c].append(n)
    print('freq', freq)


def top2(nums, k):
    count = {}

    for n in nums:
        count[n] = 1 + count.get(n, 0)

    freq = [[] for i in range(len(nums) + 1)]

    print('count', count)
    print('freq', freq)
    for n, c in count.items():
        freq[c].append(n)
    print('freq', freq)

top1([1], 1)
print()
top2([1], 1)

执行输出

count {1: 1}
freq [[], []]
freq [[1], [1]]

count {1: 1}
freq [[], []]
freq [[], [1]]

原因分析

核心问题出在**freq列表的初始化方式**上,这是你忽略的关键细节:

  • top1的初始化方式:(len(nums)+1)*[[]]
    这种写法会先创建一个空列表[],然后将这个列表的引用重复多次填充到新列表中。也就是说,freq里的所有元素指向的是同一个列表对象。当你对freq[1].append(1)进行操作时,本质是修改了那个唯一的列表,所以freq中所有位置的元素都会同步显示这个修改结果。
    针对测试用例,len(nums)=1,freq包含2个元素,这两个元素都是同一个空列表的引用。执行append操作后,这个唯一的列表变成[1],因此freq[0]和freq[1]都会显示为[1],最终输出[[1], [1]]。

  • top2的初始化方式:[[] for i in range(len(nums)+1)]
    列表推导式会在每次循环中新建一个独立的空列表,所以freq中的每个元素都是互不关联的独立对象。对freq[1].append(1)操作时,只会修改索引为1的那个列表,其他位置的列表不受影响,最终输出[[], [1]]。

简单来说,Python中用*复制可变对象时,复制的是引用而非新对象;而列表推导式会为每个元素创建新的独立对象,这就是两个函数输出差异的根本原因。


内容的提问来源于stack exchange,提问作者croatoan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 11:54:26