我有一个二维列表,列表中的元素是以字符串
为元素的列表。
由于这些字符串表示的是数字,我想把这些字符串都转换成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
这段程序能够成功,又是为什么呢?
변수는 단지 객체에 대한 포인터일 뿐입니다
이해한 다음 계속 읽으세요.
첫 번째 유형: 순회 중에 i라는 포인터가 생성되어 데이터의 요소를 가리킵니다. i=float(i)를 실행하면 새 객체 float(i)를 만들고 내가 이를 가리키게 하면 됩니다. 그게 전부입니다.
두 번째와 비슷합니다.
정확하게 말하면
으아악i = float(i)
은i
의 값을 변경하지만i
는data
요소의 복사본일 뿐이며data
의 값을 변경하지 않습니다.두 번째는 원래 목록에서 직접 작업하기 때문입니다.
으아악파이썬에서는 for를 통해 객체를 순회할 때 순회된 객체 자체를 수정할 수 없다는 것이 일반적인 규칙입니다.
일반적으로 다음 요소는 next() 메소드를 통해 얻습니다.
순회 객체 수정이 허용되면 요소의 순서에 영향을 미쳐 다음 단계의 결과를 제어할 수 없게 됩니다.
열거를 사용하여 수정하는 것을 고려해 보세요.
추가 정보는 공식 Python 매뉴얼의 for 문의 설명을 참조하세요:
https://docs.python.org/2/reference/compound_stmts.html#the-for-statement
Python의
으아악for
순회에서는 순회 객체 자체를 직접 수정하는 것이 일반적으로 권장되지 않습니다(불가능하지는 않습니다). 이렇게 하면 다음과 유사한 문제가 발생하기 때문입니다.위 프로그램은 반복할 때마다
으아악n
의 길이가 늘어나서for
가 결코 소진될 수 없기 때문에 무한 루프에 들어갑니다. 따라서 일반적으로 반복 개체의 복사본을 사용하여 순회합니다.이런 방식으로
n
값을 수정하고 순회를 성공적으로 완료할 수 있습니다.이제 예제의 첫 번째 프로그램으로 돌아가세요.
으아악사실
으아악i = float(i)
앞과 뒤의 두 개는 전혀 동일한 객체를 참조하지 않습니다. 후자의i
은data
의 요소이고 전자의i
은loadCsv
범위, 이는 Python 언어 설계에서 불합리한 지점을 포함합니다. 프로그램을 살펴보겠습니다.즉, 반복에 참여하는 식별자
으아악i
는for
루프를 종료한 후 재활용되지 않았으며 반복의 마지막 값과의 연관성을 유지하므로 전역 변수에 동일한 영향을 미칩니다 이 오류는 자주 발생합니다:for
루프 이후 전역 변수i
의 값이 설명할 수 없을 정도로 변경되었습니다. 그 이유는i
이 실제로 개체 자체가 아니지만 Python의 식별자가 개체의 속성이 아니기 때문입니다. 객체이지만 객체의 속성은 재사용 가능한 네임스페이스의 일부입니다.따라서 동일한 이름을 가진
으아악for
식별자가i
루프 내에 할당되면 상황이 달라집니다.여기서
으아악i
의 값은for
에서 할당된 값과 정확히 동일합니다. 그 이유는 Python의 할당 작업이 마지막 반복 중에 값 개체를 연결하는 작업이기 때문입니다. ,3
값은i
식별자와 연결되므로i
은 새 개체에 바인딩됩니다. 첫 번째 프로그램으로 돌아가면 다음과 같습니다.i = float(i)
는 값 개체float(i)
를 바인딩합니다.i
식별자에 할당되므로 할당된i
은data
의 요소 개체가 아니므로dataset
은 변경되지 않습니다.두 번째 프로그램은
for
내부의i
은 단지 인덱스일 뿐입니다. 수정하는 것은i
이 아니라dataset[i]
식별자와 연결된 개체이고dataset[i]
은dataset
의 구성 요소이므로data
변경될 수 있습니다.식별자와 네임스페이스에 대해서는 Python 네임스페이스 문서를 읽어보세요