it-source

목록을 되돌리거나 거꾸로 루프하려면 어떻게 해야 하나요?

criticalcode 2022. 11. 20. 12:18
반응형

목록을 되돌리거나 거꾸로 루프하려면 어떻게 해야 하나요?

Python에서 목록을 역순으로 반복하려면 어떻게 해야 하나요?

array = [0, 10, 20, 40]
for (i = array.length() - 1; i >= 0; i--)

반전 목록을 가져오려면 함수를 적용하고 항목을 에 수집합니다.

>>> xs = [0, 10, 20, 40]
>>> list(reversed(xs))
[40, 20, 10, 0]

목록을 거꾸로 반복하려면:

>>> xs = [0, 10, 20, 40]
>>> for x in reversed(xs):
...     print(x)
40
20
10
0
>>> xs = [0, 10, 20, 40]
>>> xs[::-1]
[40, 20, 10, 0]

여기서는 확장 슬라이스 구문에 대해 설명합니다.메뉴얼도 참조해 주세요.

목록을 이동하지 않고 되돌리기 위해 사용합니다.

>>> xs = [0, 10, 20, 40]
>>> xs.reverse()
>>> xs
[40, 20, 10, 0]

슬라이스를 사용하여 항목을 역순으로 새 목록을 만듭니다.

>>> xs[::-1]
[40, 20, 10, 0]

리버스 방식의 개요

목록을 되돌리는 방법에는 세 가지가 있습니다.어떤 방법이 가장 좋은지는 다음 중 어느 것이 필요한지 여부에 따라 달라집니다.

  1. 기존 목록을 이동하지 않고 되돌립니다(원래 목록 변수 변경).
    • 좋은 은 ★★★★★★★★★★★★★★★★★★★★★★」object.reverse()
  2. 역목록의 반복기를 만듭니다(for-loop, 제너레이터 등에 공급하기 때문입니다).
    • 좋은 은 ★★★★★★★★★★★★★★★★★★★★★★」reversed(object) 해서 거죠.
  3. 역순으로 목록 복사본을 만듭니다(원래 목록을 보존합니다).
    • 를 사용하는 입니다. -1단계는 -1단계는 -1단계입니다.object[::-1]

속도의 관점에서 보면 위의 내장 함수를 사용하여 목록을 되돌리는 것이 가장 좋습니다.반전의 경우, 수동으로 작성한 루프나 제너레이터에 비해 쇼트 리스트(10개 항목)에서는 2~8배, 롱 리스트에서는 최대 300배 이상 빠릅니다.이는 타당합니다. 즉, 원어민 언어(C)로 작성되고 전문가가 작성, 정밀 조사 및 최적화를 수행합니다.또한 결점이 발생하기 쉽고 모서리 케이스와 모서리 케이스를 처리할 가능성이 더 높습니다.

테스트 스크립트

이 답변의 모든 코드 스니펫을 조합하여 아래에 설명된 목록을 되돌리는 다양한 방법을 실행하는 스크립트를 만듭니다.각 메서드를 100,000회 실행하면서 시간을 설정합니다.결과는 길이 2, 10, 1000의 항목 목록에 대한 마지막 섹션에 나와 있습니다.

from timeit import timeit
from copy import copy

def time_str_ms(t):
    return '{0:8.2f} ms'.format(t * 1000)

방법 1: obj.reverse()를 사용하여 리버스 인스톨 합니다.

내일 경우 항목을 오버하거나 않고 를 하십시오.<list>.reverse()가 바뀝니다목록 개체에서 직접 실행하면 모든 항목의 순서가 바뀝니다.

다음에 따라서는 원래 변수를 반전시킬 수 있습니다.반전된 목록도 반환됩니다.즉, 이 함수 출력을 사용하여 복사본을 만들 수 있습니다.일반적으로는 이 기능을 만들지는 않지만 타이밍 스크립트에 이 기능이 필요합니다.

이 두 가지 방법의 성능을 테스트합니다.처음에는 목록을 일괄적으로 되돌리고(원래 목록을 변경), 다음으로 목록을 복사하고 나중에 되돌리고, 이것이 다른 방법과 비교하여 역복사를 만드는 가장 빠른 방법인지 확인합니다.

def rev_in_place(mylist):
    mylist.reverse()
    return mylist

def rev_copy_reverse(mylist):
    a = copy(mylist)
    a.reverse()
    return a

2: 슬라이스를 : 슬라이스를 사용하여 목록을 반전시킨다.obj[::-1]

내장된 인덱스 슬라이싱 방법을 사용하면 인덱스 객체의 일부를 복사할 수 있습니다.

  • 원래 오브젝트에는 영향을 주지 않습니다.
  • 반복자가 아닌 전체 목록을 작성합니다.

은 다음과 같습니다.<object>[first_index:last_index:step]목록을 하려면 다음을 <list>[::-1]첫 번째 크기가 인 경우 옵션을 비워두면 오브젝트의 첫 번째 요소와 마지막 요소의 기본값이 설정됩니다(스텝 크기가 음수인 경우 반전됩니다).

인덱스를 사용하면 오브젝트 인덱스의 끝에서 거꾸로 카운트되는 음수를 사용할 수 있습니다(예: -2는 마지막 항목에서 두 번째 항목).스텝 사이즈가 음수인 경우 마지막 항목부터 시작하여 그 양만큼 뒤로 인덱스됩니다.

def rev_slice(mylist):
    a = mylist[::-1]
    return a

3:의 리버스(「」3: 「」)reversed(obj)

게 요.reversed(indexed_object)★★★★

  • 그러면 목록이 아닌 역색인 반복기가 생성됩니다.대규모 리스트의 퍼포먼스를 향상시키기 위해 루프에 접속하는 경우에 최적
  • 이렇게 하면 복사본이 생성되며 원래 개체에는 영향을 주지 않습니다.

원시 반복기와 반복기에서 목록을 모두 사용하여 테스트합니다.

def reversed_iterator(mylist):
    a = reversed(mylist)
    return a

def reversed_with_list(mylist):
    a = list(reversed(mylist))
    return a

방법 4: 커스텀/수동 인덱싱을 사용한 리버스 리스트

타이밍에서 알 수 있듯이 자신만의 인덱싱 방법을 만드는 것은 좋지 않습니다.실제로 커스텀을 실시할 필요가 없는 한, 빌트인 메서드를 사용합니다.이것은 단순히 내장된 방법을 배우는 것을 의미합니다.

단, 리스트 사이즈가 작은 큰 벌칙은 없지만 스케일 업을 하면 벌칙이 엄청납니다.아래 코드는 최적화할 수 있지만, 기본 제공 메서드는 네이티브 언어로 직접 구현되기 때문에 절대 따라올 수 없습니다.

def rev_manual_pos_gen(mylist):
    max_index = len(mylist) - 1
    return [ mylist[max_index - index] for index in range(len(mylist)) ]

def rev_manual_neg_gen(mylist):
    ## index is 0 to 9, but we need -1 to -10
    return [ mylist[-index-1] for index in range(len(mylist)) ]

def rev_manual_index_loop(mylist):
    a = []
    reverse_index = len(mylist) - 1
    for index in range(len(mylist)):
        a.append(mylist[reverse_index - index])
    return a
    
def rev_manual_loop(mylist):
    a = []
    reverse_index = len(mylist)
    for index, _ in enumerate(mylist):
        reverse_index -= 1
        a.append(mylist[reverse_index])
    return a

각 방법의 타이밍

다음은 각 반전 방법을 시간 측정하기 위한 스크립트의 나머지 부분입니다., 반대로 하다, 이렇게 되어 .obj.reverse()작성하다reversed(obj)반복기는 항상 가장 빠르지만 슬라이스를 사용하는 것이 복사본을 만드는 가장 빠른 방법입니다.

그것은 또한 꼭 해야 할 경우가 아니면 스스로 그것을 하는 방법을 만들어내려고 하지 않는 것을 증명한다!

loops_to_test = 100000
number_of_items = 10
list_to_reverse = list(range(number_of_items))
if number_of_items < 15:
    print("a: {}".format(list_to_reverse))
print('Loops: {:,}'.format(loops_to_test))
# List of the functions we want to test with the timer, in print order
fcns = [rev_in_place, reversed_iterator, rev_slice, rev_copy_reverse,
        reversed_with_list, rev_manual_pos_gen, rev_manual_neg_gen,
        rev_manual_index_loop, rev_manual_loop]
max_name_string = max([ len(fcn.__name__) for fcn in fcns ])
for fcn in fcns:
    a = copy(list_to_reverse) # copy to start fresh each loop
    out_str = ' | out = {}'.format(fcn(a)) if number_of_items < 15 else ''
    # Time in ms for the given # of loops on this fcn
    time_str = time_str_ms(timeit(lambda: fcn(a), number=loops_to_test))
    # Get the output string for this function
    fcn_str = '{}(a):'.format(fcn.__name__)
    # Add the correct string length to accommodate the maximum fcn name
    format_str = '{{fx:{}s}} {{time}}{{rev}}'.format(max_name_string + 4)
    print(format_str.format(fx=fcn_str, time=time_str, rev=out_str))

타이밍 결과

그 결과 스케일링은 특정 유형의 역방향에 가장 적합한 임베디드 방식에서 가장 잘 작동하는 것으로 나타났습니다.즉, 객체 요소 수가 증가함에 따라 내장된 메서드가 다른 메서드를 훨씬 능가합니다.

수 으로는 여러 묶는 즉 된. 즉, 이 리스트는 같은 리스트의 중복 .을 하다list(reversed(obj))후(in-place)를 보다 더 작동합니다.obj.reverse()아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아.한편, 커스텀 메서드는, 리스트가 클 경우, 몇배의 시간이 걸릴 수 있습니다.

1000 항목목록과 함께 항목목록이 됩니다.reversed(<list>)function call은 30밀리초, in-place는 55밀리초, 슬라이스 방식을 사용하여 전체 반전 목록의 복사본을 만드는 데 210밀리초 정도 걸리지만 가장 빠른 수동 방식은 8400밀리초 정도 걸립니다.

목록에 2개의 항목이 있는 경우:

a: [0, 1]
Loops: 100,000
rev_in_place(a):             24.70 ms | out = [1, 0]
reversed_iterator(a):        30.48 ms | out = <list_reverseiterator object at 0x0000020242580408>
rev_slice(a):                31.65 ms | out = [1, 0]
rev_copy_reverse(a):         63.42 ms | out = [1, 0]
reversed_with_list(a):       48.65 ms | out = [1, 0]
rev_manual_pos_gen(a):       98.94 ms | out = [1, 0]
rev_manual_neg_gen(a):       88.11 ms | out = [1, 0]
rev_manual_index_loop(a):    87.23 ms | out = [1, 0]
rev_manual_loop(a):          79.24 ms | out = [1, 0]

목록에 10개의 항목이 있는 경우:

rev_in_place(a):             23.39 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
reversed_iterator(a):        30.23 ms | out = <list_reverseiterator object at 0x00000290A3CB0388>
rev_slice(a):                36.01 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
rev_copy_reverse(a):         64.67 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
reversed_with_list(a):       50.77 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
rev_manual_pos_gen(a):      162.83 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
rev_manual_neg_gen(a):      167.43 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
rev_manual_index_loop(a):   152.04 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
rev_manual_loop(a):         183.01 ms | out = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

리스트에는 1000개의 아이템이 있습니다.

rev_in_place(a):             56.37 ms
reversed_iterator(a):        30.47 ms
rev_slice(a):               211.42 ms
rev_copy_reverse(a):        295.74 ms
reversed_with_list(a):      418.45 ms
rev_manual_pos_gen(a):     8410.01 ms
rev_manual_neg_gen(a):    11054.84 ms
rev_manual_index_loop(a): 10543.11 ms
rev_manual_loop(a):       15472.66 ms

동일한 목록을 반전하려면 다음을 사용하십시오.

array.reverse()

반전 목록을 다른 목록에 할당하려면 다음 명령을 사용합니다.

newArray = array[::-1] 

예를 들어, 어레이 = 어레이[:-1]와 같은 슬라이싱을 사용하는 것은 깔끔한 트릭이며 매우 피토닉하지만 초보자에게는 조금 애매할 수 있습니다.reverse() 메서드를 사용하면 읽기 쉽기 때문에 매일 코딩하는 것이 좋습니다.

단, 인터뷰 질문에서와 같이 목록을 원래대로 되돌릴 필요가 있는 경우에는 다음과 같은 기본 제공 방법을 사용할 수 없습니다.면접관은 Python의 지식의 깊이가 아니라 문제에 어떻게 접근하는지를 볼 것입니다.알고리즘적인 접근이 필요합니다.다음 예에서는 기존 스왑을 사용하는 방법을 보여 줍니다.

def reverse_in_place(lst):      # Declare a function
    size = len(lst)             # Get the length of the sequence
    hiindex = size - 1
    its = size/2                # Number of iterations required
    for i in xrange(0, its):    # i is the low index pointer
        temp = lst[hiindex]     # Perform a classic swap
        lst[hiindex] = lst[i]
        lst[i] = temp
        hiindex -= 1            # Decrement the high index pointer
    print "Done!"

# Now test it!!
array = [2, 5, 8, 9, 12, 19, 25, 27, 32, 60, 65, 1, 7, 24, 124, 654]

print array                    # Print the original sequence
reverse_in_place(array)        # Call the function passing the list
print array                    # Print reversed list


**The result:**
[2, 5, 8, 9, 12, 19, 25, 27, 32, 60, 65, 1, 7, 24, 124, 654]
Done!
[654, 124, 24, 7, 1, 65, 60, 32, 27, 25, 19, 12, 9, 8, 5, 2]

문자열과 튜플은 불변성이기 때문에 요소를 변경하기 위해 해당 문자열에 쓸 수 없기 때문에 튜플 또는 문자열 시퀀스에서는 작동하지 않습니다.

) 라는 을 알 수긍정적이다l.reverse()Python 3 2 2 에 2 。다른 사람이 이 타이밍을 복제할 수 있는지 알고 싶습니다.

l[::-1]목록을 되돌리기 전에 복사하기 때문에 더 느릴 수 있습니다.의 추가list() 반복하다reversed(l)이치노단, 만으로 충분할 목록 복사를 할 수 있습니다. 그러나 목록을 되돌리려면 다음과 같이 하십시오.l.reverse()을 사용하다

기능들

def rev_list1(l):
    return l[::-1]

def rev_list2(l):
    return list(reversed(l))

def rev_list3(l):
    l.reverse()
    return l

목록.

l = list(range(1000000))

Python 3.5 타이밍

timeit(lambda: rev_list1(l), number=1000)
# 6.48
timeit(lambda: rev_list2(l), number=1000)
# 7.13
timeit(lambda: rev_list3(l), number=1000)
# 0.44

Python 2.7 타이밍

timeit(lambda: rev_list1(l), number=1000)
# 6.76
timeit(lambda: rev_list2(l), number=1000)
# 9.18
timeit(lambda: rev_list3(l), number=1000)
# 0.46
for x in array[::-1]:
    do stuff

및 포함:

>>> list1 = [1,2,3]
>>> reversed_list = list(reversed(list1))
>>> reversed_list
>>> [3, 2, 1]
array=[0,10,20,40]
for e in reversed(array):
  print e

reverse(array)를 사용하는 것이 가장 좋은 루트입니다.

>>> array = [1,2,3,4]
>>> for item in reversed(array):
>>>     print item

「」를 , 수 방법을 할 필요가 ?reversed.

def reverse(a):
    midpoint = len(a)/2
    for item in a[:midpoint]:
        otherside = (len(a) - a.index(item)) - 1
        temp = a[otherside]
        a[otherside] = a[a.index(item)]
        a[a.index(item)] = temp
    return a

이 작업에는 O(N) 시간이 걸립니다.

또 다른 해결책은 numpy를 사용하는 것입니다.이것을 위해 뒤집다

import numpy as np
array = [0, 10, 20, 40]
list(np.flip(array))
[40, 20, 10, 0]

에 저장하는 는, 「 리스트」를 사용할 수 .revArray = array[::-1] ★★★★★★★★★★★★★★★★★」revArray = list(reversed(array)).

그러나 첫 번째 변형은 약간 더 빠릅니다.

z = range(1000000)
startTimeTic = time.time()
y = z[::-1]
print("Time: %s s" % (time.time() - startTimeTic))

f = range(1000000)
startTimeTic = time.time()
g = list(reversed(f))
print("Time: %s s" % (time.time() - startTimeTic))

출력:

Time: 0.00489711761475 s
Time: 0.00609302520752 s

배열 인덱스의 비트 보형을 사용하여 배열 사이를 반대로 이동할 수도 있습니다.

>>> array = [0, 10, 20, 40]
>>> [array[~i] for i, _ in enumerate(array)]
[40, 20, 10, 0]

무엇을 하든 이런 으로 하지 마세요;)

어떤 논리를 사용하다

면접 연습에 구식 논리를 사용하다니

번호를 앞뒤로 교환하고 있다.의 포인터를 하여 2개의 포인터를 사용합니다.index[0] and index[last]

def reverse(array):
    n = array
    first = 0
    last = len(array) - 1
    while first < last:
      holder = n[first]
      n[first] = n[last]
      n[last] = holder
      first += 1
      last -= 1
    return n

input -> [-1 ,1, 2, 3, 4, 5, 6]
output -> [6, 5, 4, 3, 2, 1, -1]

목록 이해 사용:

[array[n] for n in range(len(array)-1, -1, -1)]

가치의 정리:

Python에서는 리스트의 순서도 정렬로 조작할 수 있으며 변수를 숫자/알파벳 순서로 정리할 수 있습니다.임시:

print(my_list)

영구:

my_list.sort(), print(my_list)

"reverse=True" 플래그를 사용하여 정렬할 수 있습니다.

print(sorted(my_list, reverse=True))

or

my_list.sort(reverse=True), print(my_list)

정리하지 않고

값을 정렬하지 않고 값을 반대로만 정렬할 수 있습니다.그러면 이렇게 할 수 있습니다.

print(list(reversed(my_list)))

** 기재 순서는 알파벳보다 숫자가 우선됩니다.Python values의 구성은 훌륭합니다.

편집 1: 잘못된 진행자가 내 답변이 사본이라고 주장하고 이전 게시물을 삭제했습니다.

인터뷰 설정이라고 가정할 때 최소한의 기능 탑재

array = [1, 2, 3, 4, 5, 6,7, 8]
inverse = [] #create container for inverse array
length = len(array)  #to iterate later, returns 8 
counter = length - 1  #because the 8th element is on position 7 (as python starts from 0)

for i in range(length): 
   inverse.append(array[counter])
   counter -= 1
print(inverse)

역목록을 취득하는 방법에는 다음 3가지가 있습니다.

  1. 1: 슬라이스 방법 1:reversed_array = array[-1::-1]

  2. 2: 슬라이스 방법 2:reversed_array2 = array[::-1]

  3. " " " " 를 사용합니다.reversed_array = array.reverse()

세 번째 함수는 실제로 목록 개체를 원래 위치로 되돌렸습니다.즉, 원래 데이터의 복사본은 유지되지 않습니다.이전 버전을 유지 보수하지 않으려면 이 방법이 좋습니다.하지만 만약 당신이 원래 버전과 역버전을 원한다면 해결책이 될 수 없을 것 같습니다.

목록을 입니다.array.

「」라고 하는 이름의 , 「」를 참조해 주세요."array"array.reverse().

매우 은 목록을 할 수 .array[:] = array[::-1].

을 Python으로 은 이 Python입니다.for★★★★★★★★

for i in xrange(len(array) - 1, -1, -1):
   print i, array[i]

이것은 다소 이해하기 어렵지만 유용할 수 있다.

def reverse(my_list):
  L = len(my_list)
  for i in range(L/2):
    my_list[i], my_list[L-i - 1] = my_list[L-i-1], my_list[i]
  return my_list
def reverse(text):
    output = []
    for i in range(len(text)-1, -1, -1):
        output.append(text[i])
    return output

리스트의 백엔드에서 스택의 맨 위에서 요소를 꺼내는 스택처럼 항상 리스트를 처리할 수 있습니다.이렇게 하면 스택의 First In Last Out 특성을 활용할 수 있습니다.물론 첫 번째 어레이를 사용하고 있습니다.저는 이 방법이 매우 직관적이기 때문에 마음에 듭니다.하나는 백엔드에서 소비되고 다른 하나는 프론트엔드에서 작성되기 때문입니다.

>>> l = [1,2,3,4,5,6]; nl=[]
>>> while l:
        nl.append(l.pop())  
>>> print nl
[6, 5, 4, 3, 2, 1]
list_data = [1,2,3,4,5]
l = len(list_data)
i=l+1
rev_data = []
while l>0:
  j=i-l
  l-=1
  rev_data.append(list_data[-j])
print "After Rev:- %s" %rev_data 
>>> l = [1, 2, 3, 4, 5]
>>> print(reduce(lambda acc, x: [x] + acc, l, []))
[5, 4, 3, 2, 1]

반대 지수의 참조를 전환하여 인플레이스 반전:

>>> l = [1,2,3,4,5,6,7]    
>>> for i in range(len(l)//2):
...     l[i], l[-1-i] = l[-1-i], l[i]
...
>>> l
[7, 6, 5, 4, 3, 2, 1]

__reverse__제너레이터를 반환합니다.

>>> l = [1,2,3,4,5]
>>> for i in l.__reversed__():
...   print i
... 
5
4
3
2
1
>>>

한 줄 코드의 사용자 입력 값 역방향:

for i in input()[::-1]: print(i,end='')

제너레이터를 사용하여 그 반전을 쉽게 평가할 수 있는 방법은 다음과 같습니다.

def reverse(seq):
    for x in range(len(seq), -1, -1): #Iterate through a sequence starting from -1 and increasing by -1.
        yield seq[x] #Yield a value to the generator

이렇게 반복합니다.

for x in reverse([1, 2, 3]):
    print(x)

목록이 필요한 경우:

l = list(reverse([1, 2, 3]))

언급URL : https://stackoverflow.com/questions/3940128/how-do-i-reverse-a-list-or-loop-over-it-backwards

반응형