[Python]list.append()在for循环中每次添加的都是最后的一个元素
被添加的对象声明,要放在for循环里面
先贴出源码吧,这段代码我想返回一个list,list中的元素由N个dict组成, dict中会包含目录下文件的名称,大小和最后修改时间(ps.大小和最后修改时间没有贴出来)
importosdef listDirectory(path): pathlist = [] info = {}ifos.path.isdir(path):forfinos.listdir(path):ifnotf.startswith('.'): #排除隐藏文件 info['name'] = f pathlist.append(info) #将dict添加进list中returnpathlist,len(pathlist)else:return-1,-1
尝试去使用这个函数查询某个文件夹下的内容时,目录文件是如下所示:
lishuo@DELL:~$ lsconnect.sh github nohup.out rjsupplicant tasks 下载
然而,在我调用这个函数去查询某个目录下的文件时,返回的list中只会显示这个文件夹下的最后一个文件,结果如下:
In [1]:fromdisp_listimportlistDirectoryIn [2]: listDirectory('/home/lishuo')Out[2]: ([{'name':'nohup.out'}, {'name':'nohup.out'}, {'name':'nohup.out'}, {'name':'nohup.out'}, {'name':'nohup.out'}, {'name':'nohup.out'}],6)
我感觉问题应该是和python的闭包有关,但是这段代码不知道该从何入手修改?请高手指导,感谢所有花时间阅读我的问题的人^_^
我来补充一点,有点进展,但是不知道为什么?
importosdef listDirectory(path): pathlist = []ifos.path.isdir(path):forfinos.listdir(path): info = {}ifnotf.startswith('.'): info['name'] = f pathlist.append(info)returnpathlist,len(pathlist)else:return-1,-1
结果:
In [1]:fromdisp_listimportlistDirectoryIn [2]: listDirectory('/home/lishuo')Out[2]: ([{'name':'github'}, {'name':'connect.sh'}, {'name':'tasks'}, {'name':'\xe4\xb8\x8b\xe8\xbd\xbd'}, {'name':'rjsupplicant'}, {'name':'nohup.out'}],6)
把info字典的定义放在for循环的里面,结果显示就正常了,百度知道查到的但是不知道为什么?字典是可变对象,初始化一定不能放在for循环内部,请问这是为什么?
9
2015-12-11 提问
已采纳
首先得知道三点。
1、程序的运行是需要去内存中申请地址的。
2、赋值操作只是对于内存中某一块地址的引用。
3、Python 内置的 id()函数。 该函数从概念上可以理解为得到当前生命下的内存地址。
id(object)
Return the “identity” of an object. This is an integer which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id() value.
CPython implementation detail: This is the address of the object in memory.
由此我们可以得到以下结果:
a =1b =1c = ad = bprint(id(1)) # value xprint(id(a)) # value xprint(id(b)) # value xprint(id(c)) # value xprint(id(d)) # value xprint(id(1) == id(a) == id(b) == id(c) == id(d)) # True
在此基础上去看 字典/dict :
当声明一个字典 info = {} 的操作时候,该字典就已经在内存中获取了某一块地址。
对该字典进行操作时,如 info['name'] = 'github' 的时候,这个字典依旧是之前所占用的地址。
可通过id 函数跟踪得到以下代码:
info = {}print(id(info))# value yinfo['name'] ='github'print(id(info))# value y
因此,对于你改进前的代码
pathlist.append(info)添加进去的始终是同一个info,准确的说,始终是同一块地址,而这个info内容在不停的修改。
参考以下代码:
info = {'name':'github'}pathlist = [info,]print(id(info))# value zprint(id(pathlist[0]))# value z
然后,对于改进后的代码
info = {} 的操作放在了循环内,结果就是每一次循环都申请使用一段新的地址,只不过依旧用info来引用。
可由一下代码对比:
info = {}print(id(info))# value minfo = {}print(id(info))# value n
两次打印的值是不等的。
另外
第一段代码中的
pathlist.append(info) #将dict添加进list中
这个注释,太多余了。
希望能帮到你。
网友评论