繁体   English   中英

从循环内返回值

[英]Returning values from inside a loop

首先,我是一个python Noob。 我可能要问的可能是常识; 但是,我很难搞清楚它。 我正在尝试创建一个函数,该函数接收读入的CSV文件并更改列表中元素的类型。 例如,如果列表被读作['A','B','2'] ,则在执行该函数后它将变为['A','B',2] 以下是我的代码:

def type_setter(x):
    x = list(x)
    for row in x:
        for i in row:
            if i.isdigit() == True:
                i = eval(i)

    return [row for row in x]

我遇到的问题是在if i.isdigit()==True: part之后返回值。 似乎值保持在循环内并且不存储到列表x中。 任何帮助是极大的赞赏。

我遇到的问题是在“if i.isdigit()== True:”部分之后返回值。 似乎值保持在循环内并且不存储到列表x中。

那是因为你没有做任何事情来将它们存储在列表中。 只是做i = eval(i)只是将局部变量i重新分配给一个新值。

例如,您可以这样做:

    for row in x:
        for index, i in enumerate(row):
            if i.isdigit() == True:
                row[index] = eval(i)

在这里,我们将列表成员row[index]重新分配给一个新值,这正是您想要做的。


一些旁注:

构建新列表通常要比尝试修改一个列表简单得多。

你应该几乎从不打电话给eval 如果要将数字转换为整数,只需使用int (对于更高级的情况,你有某种Python文字,你可能需要ast.literal_eval 。但你永远不会想要eval ,除非你真的想要运行任意代码。)

你几乎不想检查== True

此外, [row for row in x]list(x)完全相同 - 在这种情况下,它只是x的额外副本,因为您已经将x转换为列表。

如果你能找到一种方法来实现这一点,而不是两个,你不需要在顶部的x = list(x)

把它们放在一起:

def type_setter(x):
    new_x = []
    for row in x:
        new_row = []
        for i in row:
            if i.isdigit():
                new_row.append(int(i))
            else:
                new_row.append(i)
        new_x.append(new_row)
    return new_x

或者,更简洁:

def type_setter(x):
    return [[int(i) if i.isdigit() else i] for i in row] for row in x]

虽然将它作为两个表达式而不是一个表达式可能更具可读性:

def type_setter(x):
    def intify(i):
        return int(i) if i.isdigit() else i
    return [[intify(i) for i in row] for row in x]

最后一点,在Python中, EAFP (“更容易请求宽恕而非权限”,意味着你只是尝试你想做的事情,并在你不能做的时候处理错误)通常比LBYL更简单(“Look Before”你跳了“,意味着你检查你是否能够做你想做的事情。

在这种情况下可能也是如此。 例如,您想将-123视为整数而不是字符串吗? 然后i.isdigit()是错误的测试; 你需要更复杂的东西。 事实上,在这种情况下,你真正想要的测试是“是一个整数的字符串表示”,对吧? 这是一个很难在不调用int情况下编写的测试。 所以只需称呼它:

def type_setter(x):
    def intify(i):
        try:
            return int(i)
        except ValueError:
            return i
    return [[intify(i) for i in row] for row in x]

您可以直接修改列表:

def type_setter(x):
    x = list(x)
    for row_num, row in enumerate(x):
        for col_num, i in enumerate(row):
            if i.isdigit() == True:
                x[row_num][col_num] = int(i)

    return x

此外,你应该使用eval评估任何不受信任来源。 在cour情况下,您可以使用int将字符串转换为数字。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM