我是Python的新手,也是一般编程人员。虽然我认为这个问题可能与我使用异常处理有关,但也可能是由于普遍缺乏理解!
for i in range(0, len(dates)):
try:
data.append(WUF.getwx(location[j], dates[i])[1])
continue
except xml.etree.ElementTree.ParseError:
#copy last good row of data and use it for the missing day
fixdata = data[-1] #[1,2,3,4,5,6,7,8,9,10,11]
fixdata[10] = 'estimated'
data.append(fixdata)
当我按照编写的方式运行代码时,我在data
中得到2条“估计”行。一个用于上一个日期,一个用于估计的日期。如果我将fixdata
变量更改为[1, 2, 3, 4, 5, ...]
,则只会估算一行(估计日期的预期行)。
知道我在这里缺少什么吗?谢谢!
答案 0 :(得分:3)
问题在于:
fixdata = data[-1]
实际上并不复制数据,它只将引用复制到数据中。 fixdata
最终指向列表中的原始元素,因此当您执行
fixdata[10] = 'estimated'
它会更改原始数据。
要实际复制数据,请尝试以下操作:
fixdata = data[-1][:]
[:]
复制整个列表,这是我认为您正在尝试做的事情。
答案 1 :(得分:1)
听起来您正在将列表附加到data
列表中 - 创建“列表列表”。
那很好 - 我确定这是你打算做的。但是在您的异常处理程序中,您实际上是在修改现有数据:
fixdata = data[-1]
此行将引用分配到data
到fixdata
的最后一行。此时,fixdata
和data[-1]
是同一个对象。所以,当你这样做时:
fixdata[10] = 'estimated'
然后,您正在“修复”的列表仍在data
列表中,并且被名称fixdata
引用。两个名字,一个在记忆中的对象。
当你再次追加时,用
data.append(fixdata)
你仍然没有复制它;现在,您实际上有两个对data
列表中同一个对象的引用。这就是为什么看起来你有两条'估计'线 - 它们是同一个对象。
你真正想做的是复制最后一行,而不仅仅是对它的引用。将您的代码更改为:
for i in range(0, len(dates)):
try:
data.append(WUF.getwx(location[j], dates[i])[1])
continue
except xml.etree.ElementTree.ParseError:
#copy last good row of data and use it for the missing day
fixdata = data[-1][:] #[1,2,3,4,5,6,7,8,9,10,11]
fixdata[10] = 'estimated'
data.append(fixdata)
语法列表[:]是“此列表的每个元素”的简写,用作快速复制操作。然后fixdata将是它自己的列表,你可以独立改变原始元素。
答案 2 :(得分:1)
关于原始代码示例的更多评论(超出了您的问题范围)
除了索引回日期列表之外,你永远不会真正使用i变量。 Python的优势之一是它的迭代器:你可以直接在列表中的项目上迭代你的for循环,而不必计算它们并使用索引变量:
for date in dates:
您的continue语句实际上没有做任何事情。 continue
告诉解释器立即完成for循环的迭代,并立即开始下一次迭代。在这种情况下,continue
语句之后没有语句,因此循环将自然地继续,而不会被告知。
确实没有必要在两个语句中构建fixdata变量,将其附加到第三个,然后丢弃它(我们丢弃fixdata
变量,而不是其内容)你可以这样简洁地做到这一点:
data.append(data[-1][:10] + ['estimated'])
在一行中,这会将最后一行的前10个元素复制到一个新列表中,将(非常短的)列表['估计']添加到结尾,然后附加它。
如果您的第一行抛出异常,您的代码将遇到问题 - 在这种情况下,您将无法访问data[-1]
- 尝试这样做会抛出另一个异常,它将传播。最好这样防范:
except xml.etree.ElementTree.ParseError:
if data:
# do something
总而言之,我会更像这样编写代码:
for date in dates:
try:
data.append(WUF.getwx(location[j], date)[1])
except xml.etree.ElementTree.ParseError:
# as long as we've parsed at least one good row
if data:
# copy last good row of data and use it for the missing day
data.append(data[-1][:10] + ['estimated'])