0.背景
信息化老师给我布置任务来充实我颓废的寒假,遇到了这么个问题,废话也不说了,直接正题
1.问题
for program in programSpiderList
programInfoList["start"] = program.css('td::text')[0].extract()
programInfoList["title"] = program.css('td::text')[1].extract()
jsonList["fhzw"].append(programInfoList)
其中 programSpiderList 是爬虫爬下来的对象,.css是其提供的一种提取内容的方法
我将两个数据填入 programInfoList 这个字典里,再append进 fhzw 这个表
奇怪的是 fhzw 这个表,将 programSpiderList 最后一条数据重复了25遍,当然这个 programSpiderList 总共也只有25条数据
如果没看明白,我把例子简化一下
endNum = []
for num in '114514'
thenum = num + 1
endNum.append(thenum)
print endNum
你可能以为他会打印225625,但实际上打印的是555555
当然这个例子只是为了说明问题,并不严谨
2.解释
python官方给出的答案是:
在循环结束时, thenum 的值是
——Python.org(https://docs.python.org/zh-cn/3.7/faq/programming.html#id11)5
,所以所有的函数现在返回5
,即 555555 。
其实不然,如果你有心在循环中途输出 endNum 看看,就会发现:
一开始是 2
接下来是 22
然后就变成 555
下来 6666
下来 22222
最后 555555
也就是说python并没有“实时”的去修改 endNum ,而是把 thenum 的内存地址丢给了 endNum ,如果循环的过程同时去访问 endNum ,就会收到 thenum 的实时值,循环结束后再统一保存。
3.解决办法
匿名函数、copy两种都可以
匿名函数法:
endNum = []
for num in '114514'
thenum = num + 1
endNum.append(lambda x=thenum: x)
print endNum
可能有朋友要问了,那x也有内存地址啊,怎么能解决呢?
但是这匿名函数,来无影去无踪,你存储的是真正的值,而不是内存地址,每一个lambda都有不同的内存,这就是“匿名”
COPY:
import copy
endNum = []
for num in '114514'
thenum = num + 1
endNum.append(copy.copy(thenum))
print endNum
copy本身的功能大概也是创建一个新的内存地址(ID)吧?
4.评价
python循环中靠内存地址赋值,
这好吗?这不好!
我劝这两位年轻人(匿名函数、copy)好自为之,好好反思,以后不要再犯这样的错误。
python这种设计满足了:同变量相同值的赋值需求,又提供了copy这样的方法来满足同变量动态值的复制需求,细细想,真不错!!!!!!!!
感谢支持,不过不接受邀请码推广,给你屏蔽了
要是选择入住的话,可以走一下邀请码呀
这样我这边也会有优惠券的,你也不会失去什么,要是觉得这个活动不合适,也不是一定要加入的呀