0

まず、私は 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:パーツの後に値を返すことです。値がループ内にとどまり、リスト x に格納されていないようです。どんな助けでも大歓迎です。

4

2 に答える 2

2

私が抱えている問題は、「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)余分にコピーしただけです。xx

そして、これを 2 回ではなく 1 回のパスで行う方法を見つけることができれば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]

1 つではなく 2 つの式のままにしておく方が、もう少し読みやすいかもしれませんが:

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 (「前に見てください」) よりも単純です。 You Leap」とは、やりたいことができるかどうかをチェックすることを意味します)。

そして、それはこの場合に当てはまるかもしれません。たとえば-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]
于 2013-09-17T19:23:53.700 に答える
0

リストを直接変更できます。

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使用できます。int

于 2013-09-17T19:22:43.720 に答える