for循环中的try-except块跳过NEXT迭代?

时间:2017-09-10 01:55:29

标签: python for-loop try-catch

我有文本数据,我试图清理数值。我把它分成尽可能干净的行,并将行分成数据点。一个例子是

["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"]

作为输出。如果一行中没有两个非浮点数,它运行正常,但在通过异常处理删除非浮点数后,它不会打印下一个浮点值。

4 个答案:

答案 0 :(得分:2)

这看起来像是修改当前正在循环的列表的问题 - 通过删除元素,您已经更改了临时偏移的含义。一个解决方法是创建一个新列表而不是更改原始列表:

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)

但请确保您已经考虑了所有可能的情况并进行了彻底的测试。

答案 1 :(得分:1)

如果你在将迭代器保存到列表的同时修改列表,那么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

获取[&#39; 1.115&#39;,&#39; 4.3&#39;]

的结果

如果您想修改原始列表,您仍然可以这样做:

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)]

就我个人而言,我觉得列表理解方法对于这类问题最具可读性。

答案 2 :(得分:1)

改变你正在迭代的对象并不是一个好主意。列表迭代是按索引完成的,因此当您擦除一个元素时,右侧的剩余元素将向下移动。

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 = list(filter(is_float, t))

答案 3 :(得分:0)

只需将.copy()添加到循环中并删除'continue'语句:

for i in t.copy():
    try:
        print(float(i))
    except ValueError:
        print(i)
        t.remove(i)