私が抱えている問題は、「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
そして、これを 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]