我有一个二维列表,列表中的元素是以字符串
为元素的列表。
由于这些字符串表示的是数字,我想把这些字符串都转换成float
型。
def loadCsv(filename):
# 取出数据
lines = csv.reader(open(filename, 'rb'))
# 存入dataset
dataset = list(lines)
for data in dataset:
for i in data:
i = float(i) #为什么执行了该语句后i不变?
return dataset
上面这段程序执行后dataset不变,为什么i = float(i)
不能改变i的值呢?
虽然我知道这样写不是好习惯,但是想问python里for语句中所遍历的对象并不是在原对象上修改?
def loadCsv(filename):
# 取出数据
lines = csv.reader(open(filename, 'rb'))
# 存入dataset
dataset = list(lines)
for i in range(len(dataset)):
dataset[i] = [float(x) for x in dataset[i]]
return dataset
这段程序能够成功,又是为什么呢?
Une variable n'est qu'un pointeur vers un objet
Comprenez-le, puis continuez à lire.
Premier type : lors du parcours, un pointeur nommé i est créé et pointe vers un élément dans data. Lorsque vous exécutez i=float(i), vous créez simplement un nouvel objet float(i) et laissez-le pointer vers lui, c'est tout.
La deuxième méthode est la même.
Pour être précis,
i = float(i)
change la valeur dei
, maisi
n'est qu'une copie de l'élémentdata
et ne change pas la valeur dedata
, tout comme :La seconde est que vous opérez directement sur la liste originale :
En python, lors du parcours d'un objet via for, vous ne pouvez pas modifier l'objet parcouru lui-même. C'est une règle générale.
De manière générale, l'élément suivant est obtenu via la méthode next().
Si l'objet de traversée peut être modifié, cela affectera l'ordre des éléments, rendant les résultats de chaque étape suivante incontrôlables.
Pensez à utiliser enumerate pour le modifier.
Pour plus d'informations, veuillez vous référer à la description de l'instruction for dans le manuel officiel de Python :
https://docs.python.org/2/reference/compound_stmts.html#the-for-statement
Dans
for
parcours en Python, il n'est généralement pas recommandé (pas impossible) de modifier directement l'objet de parcours lui-même, car cela entraînerait des problèmes similaires aux suivants :Le programme ci-dessus entrera dans une boucle infinie car la longueur de
n
augmente à chaque itération, doncfor
ne peut jamais être épuisé, nous utilisons donc généralement une copie de l'objet itération pour parcourir :De cette façon, la valeur de
n
peut être modifiée et le parcours peut être terminé avec succès.Retournez maintenant au premier programme de votre exemple :
En fait, les deux avant et après votre
i = float(i)
ne font pas du tout référence au même objet. Ce dernieri
est un élément dedata
, et le premieri
est une variable locale dans le.loadCsv
portée. , cela implique un point déraisonnable dans la conception du langage Python, jetons un œil à un programme :C'est-à-dire que l'identifiant
i
participant à l'itération n'a pas été recyclé après la sortie de la bouclefor
, et conserve l'association avec la dernière valeur de l'itération, ce qui affectera la variable globale de même nom. Cette erreur se produit souvent :Après une boucle
for
, la valeur de la variable globalei
a changé inexplicablement. La raison en est quei
n'est pas réellement l'objet lui-même, mais l'identifiant de l'objet Python n'est pas un attribut de. l'objet, mais un attribut de l'objet. Fait partie d'un espace de noms réutilisable.Alors lorsqu'un identifiant
for
du même nom est attribué au sein de la bouclei
, la situation est différente :La valeur de
Lei
ici est exactement la même que la valeur qui lui est attribuée dansfor
La raison en est que l'opération d'affectation en Python est l'opération d'association de l'objet valeur à l'identifiant lors de la dernière itération. , la valeur3
will est associée à l'identifianti
, donci
est lié au nouvel objet. Pour revenir à votre premier programme, c'est le cas :i = float(i)
. Il lie l'objet valeurfloat(i)
à l'identifianti
, donc lei
attribué n'est pas du tout l'objet élément dedata
, doncdataset
ne sera pas modifié.Et votre deuxième programme :
à l'intérieur de
for
i
n'est qu'un index. Ce que vous modifiez n'est pasi
, mais l'objet associé à l'identifiantdataset[i]
, etdataset[i]
est un élément composant dedataset
, donc cela peut être modifiédata
.Pour les identifiants et les espaces de noms, vous pouvez lire cet article : Espaces de noms Python