这就是没学懂过C语言就开始学其他计算机语言,常常可能遇到的问题。
再碰上学的教材或者教的老师不靠谱亦或是自己没有努力思考,就很难搞懂了。
其实,现有的很多答案已经解答了这个疑问,但是,我很怀疑提问者的水平是否能理解那些答案说的意思。所以,我在这里多此一举再加一个答案,希望尽可能浅显易懂一些说明一下。
进入正题之前,为了方便别人阅读,先把你的问题代码用代码块重新贴一下。毕竟Python这种注重缩进的语法,题目描述中的代码直接就会报错了。
l = [] a = {"num": 0} for i in range(10): a["num"] = i l.append(a) print (l)
另外,再纠个错,也有其他人说过了,结果应该是10个 9
,还希望提问人仔细数数,毕竟这是学前班就应该掌握好的能力。如果实在不好数,下次别用 10
可以考虑用 3
或者 5
。
然后,先给你一个简单的解决方案:
l = [] for i in range(10): a = {"num": 0} a["num"] = i l.append(a) print (l)
这样就可以得到你想要的了。
[{'num': 0}, {'num': 1}, {'num': 2}, {'num': 3}, {'num': 4}, {'num': 5}, {'num': 6}, {'num': 7}, {'num': 8}, {'num': 9}]
为什么呢?
因为Python里面的变量并不是本体,而是对本体的引用 (reference) 。
好吧……这句话太专业了,我们换个通俗的说法。你想象Python里面变量的本体是后宫三千佳丽,那么,变量是啥呢?变量就是皇上拿来翻的牌子。你想临幸哪个胴体……不对,是变量的本体,你就翻哪个牌子。
既然是牌子,那理论上对应同一个美人,可以有好几个牌子。一个放在平时的皇宫中,一个放在某地临时行宫里,一个放在避暑山庄……这都不是问题。换句话说,牌子本身的复制并不会让美人变多。换回专业的说法,就是一个对象可以同时有多个引用,引用的复制并不影响实际对象。
回到问题里的程序上——
上来第一行,你弄了个坚挺的胸前挂着很多口袋可以装牌子的美人—— l
,对,Python里的 list
只能装牌子,永远不可能装本体。
接着,第二行你弄了个美人 {"num": 0}
,安排了一个可以临幸她的牌子 a
(其实,牌子叫啥不重要)。
+-----+ | a +--------> {"num": 0} +-----+
接下来,你把下面的事情干了10次:
临幸牌子 a
对应的美人,把她身上某个部位上印着的那个数字改成你临幸她的次数(从 0
开始计数)。(话说,怎么有点变态的感觉呢?)
然后,临幸美人 l
,把a
这个牌子给她,让她按顺序收好,这时候美人l
会复制一个牌子揣自己口袋里。
大概画一下示意图,就是这样的:箭头代表牌子对应的是哪个美人。
第0次
+-----+ | a +--------> {"num": 0} +-----+ ^ | +-----+ | | l | | +--+--+ | | | v | +======+ | | l[0] +------------+ +======+
第1次
+-----+ | a +--------> {"num": 1} +-----+ ^ | +-----+ | | l | | +--+--+ | | | v | +======+ | | l[0] +------------+ +------+ | | l[1] +------------+ +======+
第2次
+-----+ | a +--------> {"num": 2} +-----+ ^ | +-----+ | | l | | +--+--+ | | | v | +======+ | | l[0] +------------+ +------+ | | l[1] +------------+ +------+ | | l[2] +------------+ +======+
…………
第10次
+-----+ | a +--------> {"num": 9} +-----+ ^ | +-----+ | | l | | +--+--+ | | | v | +======+ | | l[0] +------------+ +------+ | | l[1] +------------+ +------+ | | l[2] +------------+ +------+ | | l[3] +------------+ +------+ | | l[4] +------------+ +------+ | | l[5] +------------+ +------+ | | l[6] +------------+ +------+ | | l[7] +------------+ +------+ | | l[8] +------------+ +------+ | | l[9] +------------+ +======+
这个时候,你把 l
这个牌子交给画师( print
),让他把你的美人的样子弄出来示众,画师找到 l
对应的美人,发现她是个挺挺的胸脯前挂着一排口袋的美人,对这种美人的默认操作,是画一对
(.)(.)
不对!应该是画一对方括号!
[]
然后把口袋里的牌子逐个翻出来,照着牌子把对应的美人一个一个画出来,放在方括号中间。
所以,这个画师,按照牌子顺序,一次次叫出已经被你蹂躏成了 {"num": 9}
的美人,画了她10次。
于是,你就看到了10个9。
那么,我后来改了之后的程序是什么样的呢?
这次把弄一个美人的语句放在循环里面了,所以,你做了10次的事情不再是在一个美人身上动手动脚10次,而是每次都弄一个新的美人来,然后某个部位上印着的那个数字改成次数,(感觉更变态了……)然后分个牌子。再把牌子给 l
这个美人。
大概画一下,是这样的。
第0次
+-----+ | a +------------------------+ +-----+ | | +-----+ | | l | | +--+--+ | | | v | +======+ | | l[0] +-------> {"num": 0} <--+ +======+
第1次
+-----+ | a +------------------------+ +-----+ | | +-----+ | | l | | +--+--+ | | | v | +======+ | | l[0] +-------> {"num": 0} | +------+ | | l[1] +-------> {"num": 1} <--+ +======+
第2次
+-----+ | a +------------------------+ +-----+ | | +-----+ | | l | | +--+--+ | | | v | +======+ | | l[0] +-------> {"num": 0} | +------+ | | l[1] +-------> {"num": 1} | +------+ | | l[2] +-------> {"num": 2} <--+ +======+
…………
第10次
+-----+ | a +------------------------+ +-----+ | | +-----+ | | l | | +--+--+ | | | v | +======+ | | l[0] +-------> {"num": 0} | +------+ | | l[1] +-------> {"num": 1} | +------+ | | l[2] +-------> {"num": 2} | +------+ | | l[3] +-------> {"num": 3} | +------+ | | l[4] +-------> {"num": 4} | +------+ | | l[5] +-------> {"num": 5} | +------+ | | l[6] +-------> {"num": 6} | +------+ | | l[7] +-------> {"num": 7} | +------+ | | l[8] +-------> {"num": 8} | +------+ | | l[9] +-------> {"num": 9} <--+ +======+
这次,你再把 l
这个牌子交给画师,画师同样把十个牌子的美人都画一次,但这次则是十个美人,那个部位的数字各有不同,所以,得到了你想要的 0到9。
按正常双休的话,这些美人,够你夜夜欢愉俩星期不重样的了。年轻人要注意身体啊!要不就多补补,去学习一下内存的知识吧!
对引用什么的有兴趣,也可以来看看我这个万年没更新的专栏:
看漫画·做实验·学编程
啥时候会更新这个问题,上帝说:“我是看不到了……”