이 반복적 인리스트 증가 코드가 왜 IndexError :리스트 할당 인덱스가 범위를 벗어 납니까?


194

다음 코드를 고려하십시오 :

i = [1, 2, 3, 5, 8, 13]
j = []
k = 0

for l in i:
    j[k] = l
    k += 1

print j

출력 (Win 7 32 비트의 Python 2.6.6)은 다음과 같습니다.

> Traceback (most recent call last): 
>     j[k] = l IndexError: list assignment index out of range

나는 그것이 이해하지 못하는 단순한 것 같아요. 누군가 그것을 정리할 수 있습니까?


7
append는 사용 사례에 적합한 솔루션이지만 파이썬 목록에는 목록의 i 위치에 직접 삽입 할 수있는 삽입 방법이 있습니다. j.insert(k, l)
opensourcegeek

OP의 솔루션이 작동하지 않는 이유는 무엇입니까? 왜 append를 사용합니까?
Helen

답변:


317

j는 빈 목록이지만 [0]아직 존재하지 않는 첫 번째 반복에서 요소 에 쓰려고합니다 .

대신 목록 끝에 새 요소를 추가하려면 다음을 시도하십시오.

for l in i:
    j.append(l)

물론 기존 목록을 복사하기 만하면 실제로는이 작업을 수행 할 수 없습니다. 당신은 단지 할 것입니다 :

j = list(i)

또는 다른 언어의 배열처럼 Python 목록을 사용하려는 경우 요소를 null 값으로 설정 한 목록 ( None아래 예)을 사용하여 목록을 미리 만든 다음 나중에 특정 위치의 값을 덮어 쓸 수 있습니다.

i = [1, 2, 3, 5, 8, 13]
j = [None] * len(i)
#j == [None, None, None, None, None, None]
k = 0

for l in i:
   j[k] = l
   k += 1

알아야 할 것은 list개체가 존재하지 않는 인덱스에 값을 할당 할 수 없다는 것입니다.


2
고마워요 나는 거의 3 가지 같은 대답이 있기 때문에 어느 것을 칭찬해야하는지 몰랐습니다. 이것은 내가 생각하는 가장 설명적인 것입니다. 건배
Vladan

PHP 나 C와 같은 다른 언어를 사용하는 사람들에게는 이것이 매우 혼란 스러울 수 있습니다. j는 배열이 아니라 목록의 한 유형입니다. 목록 유형을 사용하면 이것이 첨자 형이라고 생각하지 않습니다. 다른 언어에서 오면 매우 혼란 스럽다.
Nguai al

@Nguaial 목록 유형은 아래 첨자가 가능하지만 이미 존재하는 요소에만 액세스 할 수 있습니다. 범위를 벗어난 인덱스에 쓰려고하면 요소를 만들 수 없습니다. 목록에 이미 하나 이상의 요소가 있으면 j [0] = "foo"가 작동합니다.
Steve Mayne

52

다른 옵션은 초기화하는 것입니다 j.

j = [None] * len(i)

3
max 대신 len (i)을 사용하려고합니다.
Steve Mayne

25

수행 j.append(l)대신 j[k] = l하고 피하기는 k전혀.


2
더 짧은 (? 더 파이썬) 방법이있을 수 있습니다j+=[l]
올레 Prypin

2
@BlaXpirit : 가비지 수집기에 부담을 줄 것입니다.
khachik

2
@ BalXpirit : 주어진 문자는 몇 문자 만 저장하고 (특히 허용 할 수 있도록 공백을 추가해야하기 때문에) .append훨씬 더 일반적입니다 (아마 이유-이해하기가 약간 더 쉽다고 생각합니다). 어떠한 방식으로. (@khachik 편집 : 아니요, 내부 +=수정)

15

당신은 또한 목록 이해를 사용할 수 있습니다 :

j = [l for l in i]

또는 진술을 사용하여 사본을 만드십시오.

j = i[:]

그 두 번째 건설은 깔끔합니다
javadba

2
목록을 복사하는 것이 유일한 목표라면 간단히 j = list (i)라고 말할 수 있습니다. 질문은 특별히 요소를 복사하는 방법이 필요하지 않고 목록의 동작에 관한 것입니다.
Steve Mayne

10
j.append(l)

또한 소문자 "L"은 1과 혼동하기 쉽기 때문에 사용하지 마십시오.


7

나는 파이썬 메소드 삽입 이 당신이 찾고있는 것이라고 생각합니다 .

위치 i에 요소 x를 삽입합니다. list.insert (i, x)

array = [1,2,3,4,5]

array.insert(1,20)

print(array)

# prints [1,2,20,3,4,5]

1
이 목적을 위해 특별히 제공된 insert시기 append를 사용하는 것은 중요하지 않습니다 .
holdenweb

정보의 관점에서 코드는 실제로 인쇄 [1, 20, 2, 3, 4, 5]됩니다.
holdenweb

인덱스 1에 삽입하여 인덱스 1 이상을 대체했습니다. 삽입 된 값은 인덱스 2에서 끝나지 않습니다. Iist.insert ()는 목록 끝에 항목을 추가하지 않으려는 경우에만 필요합니다. 여기서 질문은 정확히 그렇게하므로 list.append ()가 바람직합니다.
Martijn Pieters

실제로 내가 왜 이런 질문에 대답했는지 놀라게된다. 나는 그것이 사람들을 돕거나 그들의 문제를 해결할 아이디어를 주어서 5 명중을 얻는다고 생각합니다.
Mehmet Kagan Kayaalp

5

j에 대한 사전 (연관 배열과 유사)을 사용할 수 있습니다.

i = [1, 2, 3, 5, 8, 13]
j = {} #initiate as dictionary
k = 0

for l in i:
    j[k] = l
    k += 1

print j

인쇄합니다 :

{0: 1, 1: 2, 2: 3, 3: 5, 4: 8, 5: 13}

0에서 시작하는 연속 인덱스의 경우 매핑은 일반적으로 잘못된 데이터 구조입니다. 특히 매핑이 특정 순서를 전달하지 않기 때문에 슬라이싱 또는 반전이없는 경우입니다.
Martijn Pieters

2

한 가지 더 방법 :

j=i[0]
for k in range(1,len(i)):
    j = numpy.vstack([j,i[k]])

이 경우 jnumpy 배열이됩니다.


0

아마 당신은 extend () 가 필요할 것입니다

i=[1,3,5,7]
j=[]
j.extend(i)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.