[英]try-except block in for loop skips NEXT iteration?
我有试图清除数值的文本数据。 我将其尽可能细分为干净的行,并将这些行分成数据点。 一个例子是
["1.115","","","4.3"]
我的代码应该将其变成
["1.115","4.3"]
这是代码段:
for i in t:
try:
print(float(i))
except ValueError:
print(i)
t.remove(i)
continue
所有的print()语句都可用于调试。 运行代码可以
["1.115","","4.3"]
作为输出。 如果连续没有两个非浮点数,则可以正常运行,但是在通过异常处理删除了一个非浮点数后,它不会打印下一个浮点数。
这看起来像是修改当前正在循环的列表的问题-通过删除元素,您已经更改了固化剂偏移量的含义。 一种解决方法是创建一个新列表,而不是更改原始列表:
t = ["1.115", "", "", "4.3"]
s = []
for i in t:
try:
s.append(float(i))
except ValueError:
pass
print(s)
如果您确实想循环修改原始列表,则可以尝试如下操作:
t = ["1.115", "", "", "4.3"]
i = 0
while i < len(t):
try:
float(t[i])
i += 1
except ValueError:
del t[i]
print(t)
但是,请确保您已考虑所有可能的情况并进行了全面测试。
如果要在保留列表迭代器的同时修改列表,Python(和大多数语言)很有可能会感到困惑。
此代码很容易解决该问题,因为您正在修改要遍历的相同列表。 构造一个新列表作为输出更为常见。 这是一个例子:
def yield_only_floats(l):
for s in l:
try:
float(s)
yield s
except ValueError:
pass
x = list(yield_only_floats(["1.115","","","4.3"]))
print x
得到的结果为['1.115','4.3']
如果要修改原始列表,仍然可以执行以下操作:
x = ["1.115","","","4.3"]
x[:] = list(yield_only_floats(x))
但是,如果您确实要在迭代时修改要迭代的同一列表,则最好的想法是反向迭代:
def leave_only_floats(l):
for i in xrange(len(l) - 1, -1, -1):
try:
float(l[i])
except ValueError:
del l[i]
x = ["1.115","","","4.3"]
leave_only_floats(x)
请注意,我还使用了位置删除,而不是值删除,这使其速度更快(列表不必再次搜索)
顺便说一句,您还可以考虑使用列表理解:
def is_float(s):
try:
float(s)
return True
except ValueError:
return False
x = ["1.115","","","4.3"]
y = [s for s in x if is_float(s)]
就我个人而言,我认为列表理解方法对于此类问题最易读。
更改要迭代的对象不是一个好主意。 列表迭代是逐个索引完成的,因此,当您擦除一个元素时,右侧的其余元素将向下移动。
t = ["1.115", "", "", "4.3"]
for i in t:
try:
print(float(i))
except ValueError:
print(i)
t.remove(i)
# First run of loop:
idx = 0
i = "1.115"
t = ["1.115", "", "", "4.3"]
# Second run of loop
idx = 1
i = ""
t = ["1.115", "", "4.3"]
# Third, last run of loop
idx = 2
i = "4.3"
t = ["1.115", "", "4.3"]
正确的方法是:
t = ["1.115","","","4.3"]
def is_float(number):
try:
float(number)
return True
except ValueError:
return False
res = [x for x in t if is_float(x)]
只需在循环中添加.copy()并删除“ continue”语句:
for i in t.copy():
try:
print(float(i))
except ValueError:
print(i)
t.remove(i)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.