星期一, 七月 30, 2007

python list pop operation 的一个典型

下面可能可以算得上是一个 List pop 操作的典型情况,是在一段单元测试代码中,我需要对某个目录下的文件进行查找,找到所有比指定时间要新的普通文件:
basedir = "/usr/local"
txlist = ["t:%s/etc" % basedir, "t:%s/share" % basedir, "x:%s/share/man"]

expect = []
for fname in self.__find_rfiles("%s/etc" % basedir): expect.append(fname)
for fname in self.__find_rfiles("%s/share" % basedir): expect.append(fname)
for fname in self.__find_rfiles("%s/share/man" % basedir): exclude.append(fname)
for fname in exclude: expect.remove(fname)
j = random.randint(0, len(expect))
ftemp = expect[j]
temp = os.lstat(ftemp)[-1]
ttemp = datetime.datetime(*time.localtime(temp)[:6])
rmidx = []
# #1:
for fname in expect:
temp = os.lstat(fname)[-1]
fctime = datetime.datetime(*time.localtime(temp)[:6])
if fctime > ttemp: rmidx.append(fname)
# #2:
for fname in rmidx:
expect.remove(fname)

fsbk = fs_backup.FsBackup(identity='test')
fsbk.append(txlist)
_files = fsbk.find(lasttime=ttemp)
_files.sort()
expect.sort()
self.failUnlessEqual(_files, expect)
self.__clean_last(fsbk)
这里,首先无法在位置 #1 处直接对 expect 进行 remove() 或 pop() 操作,因为这个操作会对当前列表的索引产生影响,导致当前位置指针指向了错误的项,所以会漏掉下一个节点,这在:python list pop in loop 中已经说明。

一种办法是使用在 python list pop in loop, 补充 中说明的方法,对指针进行调整。而这里采用另一种方法,建立一个不同的索引,每次都对重新寻找 expect 中指定节点的位置,这样指针位置就不会错了。

如果列表很大,那么每次搜寻索引可能会导致开销很大,那么可以考虑使用 dict(hash table) 来替换列表!

没有评论: