python中for语句中对当前遍历对象赋值的问题?
PHP中文网
PHP中文网 2017-04-17 17:23:44
0
4
985

我有一个二维列表,列表中的元素是以字符串为元素的列表。
由于这些字符串表示的是数字,我想把这些字符串都转换成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

这段程序能够成功,又是为什么呢?

PHP中文网
PHP中文网

认证高级PHP讲师

모든 응답(4)
迷茫

변수는 단지 객체에 대한 포인터일 뿐입니다

이해한 다음 계속 읽으세요.

첫 번째 유형: 순회 중에 i라는 포인터가 생성되어 데이터의 요소를 가리킵니다. i=float(i)를 실행하면 새 객체 float(i)를 만들고 내가 이를 가리키게 하면 됩니다. 그게 전부입니다.

두 번째와 비슷합니다.

左手右手慢动作

정확하게 말하면 i = float(i)i의 값을 변경하지만 idata 요소의 복사본일 뿐이며 data의 값을 변경하지 않습니다.

으아악

두 번째는 원래 목록에서 직접 작업하기 때문입니다.

으아악
PHPzhong

파이썬에서는 for를 통해 객체를 순회할 때 순회된 객체 자체를 수정할 수 없다는 것이 일반적인 규칙입니다.
일반적으로 다음 요소는 next() 메소드를 통해 얻습니다.
순회 객체 수정이 허용되면 요소의 순서에 영향을 미쳐 다음 단계의 결과를 제어할 수 없게 됩니다.
열거를 사용하여 수정하는 것을 고려해 보세요.

열거(데이터)의 i,v에 대해:

으아아아

이때 iteration 객체는 data가 아닌 enumerate(data)이므로 수정이 가능합니다.

추가 정보는 공식 Python 매뉴얼의 for 문의 설명을 참조하세요:
https://docs.python.org/2/reference/compound_stmts.html#the-for-statement

伊谢尔伦

Python의 for 순회에서는 순회 객체 자체를 직접 수정하는 것이 일반적으로 권장되지 않습니다(불가능하지는 않습니다). 이렇게 하면 다음과 유사한 문제가 발생하기 때문입니다.

으아악

위 프로그램은 반복할 때마다 n의 길이가 늘어나서 for가 결코 소진될 수 없기 때문에 무한 루프에 들어갑니다. 따라서 일반적으로 반복 개체의 복사본을 사용하여 순회합니다.

으아악

이런 방식으로 n 값을 수정하고 순회를 성공적으로 완료할 수 있습니다.

이제 예제의 첫 번째 프로그램으로 돌아가세요.

으아악

사실 i = float(i) 앞과 뒤의 두 개는 전혀 동일한 객체를 참조하지 않습니다. 후자의 idata의 요소이고 전자의 iloadCsv 범위, 이는 Python 언어 설계에서 불합리한 지점을 포함합니다. 프로그램을 살펴보겠습니다.

으아악

즉, 반복에 참여하는 식별자 ifor 루프를 종료한 후 재활용되지 않았으며 반복의 마지막 값과의 연관성을 유지하므로 전역 변수에 동일한 영향을 미칩니다 이 오류는 자주 발생합니다:

으아악

for 루프 이후 전역 변수 i의 값이 설명할 수 없을 정도로 변경되었습니다. 그 이유는 i이 실제로 개체 자체가 아니지만 Python의 식별자가 개체의 속성이 아니기 때문입니다. 객체이지만 객체의 속성은 재사용 가능한 네임스페이스의 일부입니다.

따라서 동일한 이름을 가진 for 식별자가 i 루프 내에 할당되면 상황이 달라집니다.

으아악

여기서 i의 값은 for에서 할당된 값과 정확히 동일합니다. 그 이유는 Python의 할당 작업이 마지막 반복 중에 값 개체를 연결하는 작업이기 때문입니다. , 3 값은 i 식별자와 연결되므로 i은 새 개체에 바인딩됩니다. 첫 번째 프로그램으로 돌아가면 다음과 같습니다. i = float(i)는 값 개체 float(i)를 바인딩합니다. i 식별자에 할당되므로 할당된 idata의 요소 개체가 아니므로 dataset은 변경되지 않습니다.
두 번째 프로그램은

으아악

for 내부의 i은 단지 인덱스일 뿐입니다. 수정하는 것은 i이 아니라 dataset[i] 식별자와 연결된 개체이고 dataset[i]dataset의 구성 요소이므로 data 변경될 수 있습니다.

식별자와 네임스페이스에 대해서는 Python 네임스페이스 문서를 읽어보세요

최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿