파이썬에서 목록을 역순으로 순회


701

그래서 시작 len(collection)하고 끝날 수 있습니다 collection[0].

또한 루프 인덱스에 액세스 할 수 있기를 원합니다.

답변:


1181

내장 reversed()기능을 사용하십시오 .

>>> a = ["foo", "bar", "baz"]
>>> for i in reversed(a):
...     print(i)
... 
baz
bar
foo

원래 색인에 액세스하려면 enumerate()목록에 다음을 전달하기 전에 사용 하십시오 reversed().

>>> for i, e in reversed(list(enumerate(a))):
...     print(i, e)
... 
2 baz
1 bar
0 foo

이후 enumerate()반환 발전기 및 발전기는 되돌릴 수 없습니다, 당신은으로 변환 할 필요가 list첫번째.


130
복사가 생성되지 않고 이송 중에 요소가 즉시 반전됩니다! 이것은 모든 반복 기능의 중요한 기능입니다 (모두 "ed"로 끝남).
Konrad Rudolph

9
@Greg Hewgill 아니요, 원본의 반복자이며 사본이 만들어지지 않았습니다!
André

92
혼동을 피하려면 : reversed()목록을 수정하지 마십시오. reversed()목록의 복사본을 만들지 않습니다 (그렇지 않으면 O (N) 추가 메모리가 필요함). 리스트를 수정해야한다면 alist.reverse(); 역순으로 목록의 사본이 필요한 경우을 사용하십시오 alist[::-1].
jfs

90
이 답변에서 list (enumerate (a))는 사본을 만듭니다.
Triptych 2012

42
@ JF, reversed ()는 복사본을 만들지 않지만 list (enumerate ())는 복사본을 만듭니다.
Triptych 2012

172

넌 할 수있어:

for item in my_list[::-1]:
    print item

(또는 for 루프에서 수행하려는 모든 작업)

[::-1]슬라이스 for 루프의 목록을 반전 (실제로 목록 "영구적"을 수정하지 않습니다).


24
[::-1]얕은 사본을 생성하므로 "영구적으로"또는 "임시"로 배열을 변경하지 않습니다.
jfs

6
이것은 적어도 Python 2.7 (테스트)에서 reverse를 사용하는 것보다 약간 느립니다.
kgriffs

14
어떻게 이런 대답이 작품 : 그것은 분리 된 매개 변수를 사용하여 목록의 복사본을 생성 시작점을 : 지정되지 않은, (말에 시작하므로 목록의 길이가된다) 엔드 포인트 : 지정되지 않은 (이외의 매직 번호가됩니다 0아마는 -1, 시작에서 끝 그래서 ) 및 단계 : -1( 1한 번에 목록, 항목을 거꾸로 반복 ).
Edward

1
나는 이것도 테스트했다 (python 2.7). [::-1] vs.reversed()
RustyShackleford

67

루프 인덱스가 필요하고 전체 목록을 두 번 탐색하거나 추가 메모리를 사용하지 않으려면 생성기를 작성하십시오.

def reverse_enum(L):
   for index in reversed(xrange(len(L))):
      yield index, L[index]

L = ['foo', 'bar', 'bas']
for index, item in reverse_enum(L):
   print index, item

3
enumerate_reversed 함수를 호출하지만 내 취향 일뿐입니다. 귀하의 답변이 특정 질문에 가장 깨끗하다고 ​​생각합니다.
tzot

1
reversed(xrange(len(L)))와 동일한 인덱스를 생성합니다 xrange(len(L)-1, -1, -1).
jfs 2016

2
이해가 적은 움직이는 부품을 선호 :for index, item in enumerate(reversed(L)): print len(L)-1-index, item
돈 커크비

2
@Triptych 나는 reversed ()에서 열거하면 역 인덱스를 생성하지 않으며 코드가 많은 도움이된다는 사실에 대처해야했습니다. 이 방법은 표준 라이브러리에 있어야합니다.
oski86

2
reversed (xrange ())는 xrange 객체에 __len__ 및 __getitem__ 메서드뿐만 아니라 __reversed__ 메서드가 있으며 reversed는이를 감지하여 사용할 수 있기 때문에 작동합니다. 그러나 열거 객체에는 __reversed__, __len__ 또는 __getitem__이 없습니다. 그러나 열거하지 않습니까? 모르겠어요
FutureNerd

60

다음과 같이 할 수 있습니다 :

범위 내 i의 경우 (len (collection) -1, -1, -1) :
    인쇄 수집 [i]

    파이썬 3에 대한 # print (collection [i])

그래서 당신의 추측은 꽤 가까웠습니다 :) 약간 어색하지만 기본적으로 말합니다 : 1 미만으로 시작하고 len(collection)-1 바로 전에 -1 단계까지 갈 때까지 계속하십시오.

참고로, help함수는 파이썬 콘솔에서 무언가에 대한 문서를 볼 수 있기 때문에 매우 유용합니다.

help(range)


1
3.0 이전의 Python 버전의 경우 xlen이 큰 len (collection)의 범위보다 바람직하다고 생각합니다.
Brian M. Hunt

나는 당신이 옳다고 생각합니다 :) iirc, range ()는 전체 범위를 배열로 생성하지만 xrange ()는 필요할 때만 값을 생성하는 반복자를 반환합니다.
Alan Rowarth

11
이것은 너무 많은 것 때문에 너무 이상하게 보입니다 -1. 그냥 말하고 싶습니다reversed(xrange(len(collection)))
musiphil

22

reversed내장 기능이 편리합니다 :

for item in reversed(sequence):

문서 반전을위한 그것의 한계를 설명합니다.

인덱스와 함께 시퀀스를 거꾸로 걸어야하는 경우 (예 : 시퀀스 길이를 변경하는 내부 수정의 경우)이 함수에 내 codeutil 모듈을 정의했습니다.

import itertools
def reversed_enumerate(sequence):
    return itertools.izip(
        reversed(xrange(len(sequence))),
        reversed(sequence),
    )

이것은 시퀀스의 사본을 생성하지 않습니다. 분명히, reversed여전히 제한 사항이 적용됩니다.


9

새 목록을 다시 만들지 않고 색인을 생성하면 어떨까요?

>>> foo = ['1a','2b','3c','4d']
>>> for i in range(len(foo)):
...     print foo[-(i+1)]
...
4d
3c
2b
1a
>>>

또는

>>> length = len(foo)
>>> for i in range(length):
...     print foo[length-i-1]
...
4d
3c
2b
1a
>>>

9
>>> l = ["a","b","c","d"]
>>> l.reverse()
>>> l
['d', 'c', 'b', 'a']

또는

>>> print l[::-1]
['d', 'c', 'b', 'a']

7

나는 한 줄짜리 발전기 접근 방식을 좋아합니다.

((i, sequence[i]) for i in reversed(xrange(len(sequence))))

7

또한 "range"또는 "count"기능을 사용할 수 있습니다. 다음과 같이 :

a = ["foo", "bar", "baz"]
for i in range(len(a)-1, -1, -1):
    print(i, a[i])

3 baz
2 bar
1 foo

itertools에서 "count"를 다음과 같이 사용할 수도 있습니다.

a = ["foo", "bar", "baz"]
from itertools import count, takewhile

def larger_than_0(x):
    return x > 0

for x in takewhile(larger_than_0, count(3, -1)):
    print(x, a[x-1])

3 baz
2 bar
1 foo

첫 번째 블록의 코드는 올바른 출력을 생성하지 않습니다. 출력은 실제로3 foo\n2 bar\n1 baz
amiller27

첫 번째 예에서 "a [i-1]"을 사용하지 않으려면이 범위 "range (len (a) -1, -1, -1)"을 사용하십시오. 이것은 더 간단합니다.
Francisc


4

수입이없는 접근법 :

for i in range(1,len(arr)+1):
    print(arr[-i])

또는

for i in arr[::-1]:
    print(i)

3
def reverse(spam):
    k = []
    for i in spam:
        k.insert(0,i)
    return "".join(k)

3

그만한 가치가 있기 때문에 당신도 이렇게 할 수 있습니다. 매우 간단합니다.

a = [1, 2, 3, 4, 5, 6, 7]
for x in xrange(len(a)):
    x += 1
    print a[-x]

1
당신은 또한 할 수 print a[-(x+1)]및 피하기는 루프의 본문에 인덱스를 재 할당.
Malcolm

2

reverse(enumerate(collection))파이썬 3에서 표현하는 표현 방법 :

zip(reversed(range(len(collection))), reversed(collection))

파이썬 2에서 :

izip(reversed(xrange(len(collection))), reversed(collection))

왜 우리가 이것에 대한 속기가 없는지 잘 모르겠습니다.

def reversed_enumerate(collection):
    return zip(reversed(range(len(collection))), reversed(collection))

왜 우리가 없는지 reversed_range()


2

색인이 필요하고 목록이 작은 경우 가장 읽기 쉬운 방법은 reversed(list(enumerate(your_list)))허용되는 답변의 답변과 같습니다. 그러나 이것은 목록의 사본을 생성하므로 목록이 메모리의 많은 부분을 차지하면 enumerate(reversed())에서에서 반환 한 색인을 빼야합니다 len()-1.

한 번만 수행해야하는 경우 :

a = ['b', 'd', 'c', 'a']

for index, value in enumerate(reversed(a)):
    index = len(a)-1 - index

    do_something(index, value)

또는 여러 번이 작업을 수행 해야하는 경우 발전기를 사용해야합니다.

def enumerate_reversed(lyst):
    for index, value in enumerate(reversed(lyst)):
        index = len(lyst)-1 - index
        yield index, value

for index, value in enumerate_reversed(a):
    do_something(index, value)

1

역 기능은 여기에 유용합니다 :

myArray = [1,2,3,4]
myArray.reverse()
for x in myArray:
    print x

list.reverse ()에는 반환 값이 없습니다.
게오르그 Schölly

1

while루프를 사용할 수도 있습니다 .

i = len(collection)-1
while i>=0:
    value = collection[i]
    index = i
    i-=1

1

일반적인 for 루프에서 음수 인덱스를 사용할 수 있습니다.

>>> collection = ["ham", "spam", "eggs", "baked beans"]
>>> for i in range(1, len(collection) + 1):
...     print(collection[-i])
... 
baked beans
eggs
spam
ham

컬렉션의 역전 된 복사본을 반복하여 인덱스에 액세스하려면 다음을 사용하십시오 i - 1.

>>> for i in range(1, len(collection) + 1):
...     print(i-1, collection[-i])
... 
0 baked beans
1 eggs
2 spam
3 ham

반전되지 않은 원래 색인에 액세스하려면 len(collection) - i다음을 사용하십시오 .

>>> for i in range(1, len(collection) + 1):
...     print(len(collection)-i, collection[-i])
... 
3 baked beans
2 eggs
1 spam
0 ham

1

인덱스가 음수인지 상관하지 않으면 다음을 수행 할 수 있습니다.

>>> a = ["foo", "bar", "baz"]
>>> for i in range(len(a)):
...     print(~i, a[~i]))
-1 baz
-2 bar
-3 foo

1

가장 우아한 방법은 다음 생성기 를 변환 enumerate하고 reversed사용하는 것입니다.

(-(ri+1), val) for ri, val in enumerate(reversed(foo))

enumerate반복자 의 역순을 생성 합니다

예:

foo = [1,2,3]
bar = [3,6,9]
[
    bar[i] - val
    for i, val in ((-(ri+1), val) for ri, val in enumerate(reversed(foo)))
]

결과:

[6, 4, 2]

0

다른 답변은 좋지만 목록 이해 스타일로 사용하려면

collection = ['a','b','c']
[item for item in reversed( collection ) ]

1
이것이 반전 (수집)과 동일하지 않습니까? 목록 이해력을 추가하면 불필요한 계산을 제외하고 아무 것도 수행하지 않습니다. 마치 a = [[1, 2, 3]의 항목에 대한 항목] 대 a = [1, 2, 3]을 쓰는 것과 같습니다.
EpicDavi 2016 년

0

음의 인덱스를 사용하려면 : -1에서 시작하고 각 반복에서 -1 씩 뒤로 이동하십시오.

>>> a = ["foo", "bar", "baz"]
>>> for i in range(-1, -1*(len(a)+1), -1):
...     print i, a[i]
... 
-1 baz
-2 bar
-3 foo

0

간단한 방법 :

n = int(input())
arr = list(map(int, input().split()))

for i in reversed(range(0, n)):
    print("%d %d" %(i, arr[i]))

0
input_list = ['foo','bar','baz']
for i in range(-1,-len(input_list)-1,-1)
    print(input_list[i])

나는 이것도 그것을 할 수있는 간단한 방법이라고 생각합니다. 끝에서 읽고 목록의 길이까지 계속 줄입니다. 우리는 "끝"인덱스를 실행하지 않기 때문에 -1도 추가했습니다.


0

작업이 목록에서 어떤 조건을 만족시키는 마지막 요소를 찾는 것이라고 가정합니다 (즉, 뒤로 볼 때 먼저), 다음과 같은 숫자가 나타납니다.

>>> min(timeit.repeat('for i in xrange(len(xs)-1,-1,-1):\n    if 128 == xs[i]: break', setup='xs, n = range(256), 0', repeat=8))
4.6937971115112305
>>> min(timeit.repeat('for i in reversed(xrange(0, len(xs))):\n    if 128 == xs[i]: break', setup='xs, n = range(256), 0', repeat=8))
4.809093952178955
>>> min(timeit.repeat('for i, x in enumerate(reversed(xs), 1):\n    if 128 == x: break', setup='xs, n = range(256), 0', repeat=8))
4.931743860244751
>>> min(timeit.repeat('for i, x in enumerate(xs[::-1]):\n    if 128 == x: break', setup='xs, n = range(256), 0', repeat=8))
5.548468112945557
>>> min(timeit.repeat('for i in xrange(len(xs), 0, -1):\n    if 128 == xs[i - 1]: break', setup='xs, n = range(256), 0', repeat=8))
6.286104917526245
>>> min(timeit.repeat('i = len(xs)\nwhile 0 < i:\n    i -= 1\n    if 128 == xs[i]: break', setup='xs, n = range(256), 0', repeat=8))
8.384078979492188

따라서 가장 추한 옵션 xrange(len(xs)-1,-1,-1)이 가장 빠릅니다.


-1

발전기를 사용할 수 있습니다 :

li = [1,2,3,4,5,6]
len_li = len(li)
gen = (len_li-1-i for i in range(len_li))

드디어:

for i in gen:
    print(li[i])

이것이 당신을 돕기를 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.