簡體   English   中英

如何在適當的位置反轉列表中的子列表?

[英]How do I reverse a sublist in a list in place?

我應該創建一個函數,它的輸入是一個列表和兩個數字,該函數反轉子列表,它的位置由兩個數字表示。 例如,這是它應該做的:

>>> lst = [1, 2, 3, 4, 5] 
>>> reverse_sublist (lst,0,4) 
>>> lst  [4, 3, 2, 1, 5]

我創建了一個函數並且它可以工作,但我不確定它是否到位。 這是我的代碼:

def reverse_sublist(lst,start,end):
    sublist=lst[start:end]
    sublist.reverse()
    lst[start:end]=sublist
    print(lst)
def reverse_sublist(lst,start,end):
    lst[start:end] = lst[start:end][::-1]
    return lst

不帶臨時列表的部分反向(如果使用 Python 2,則用xrange替換range ):

def partial_reverse(list_, from_, to):
    for i in range(0, int((to - from_)/2)):
        (list_[from_+i], list_[to-i]) = (list_[to-i], list_[from_+i])

list_ = [1, 2, 3, 4, 5, 6, 7, 8]
partial_reverse(list_, 3, 7)
print(list_)

以部分或完整方式反轉列表的最簡單方法。

listVar = ['a','b','c','d']
def listReverse(list,start,end):
    while(start<end):
        temp = list[start]
        list[start] = list[end] #Swaping
        list[end]=temp
        start+=1
        end-=1
    print(list)


listReverse(listVar,1,3)

輸出: - ['a', 'd', 'c', 'b']

...我不確定它是否到位。

...

 lst[start:end]=sublist

是的,它就位。 lst永遠不會反彈,只有它的對象發生了變異。

只需使用切片:

>>> lst = [1, 2, 3, 4, 5] 
>>> lst[0:len(lst[3::-1])]=lst[3::-1]
>>> lst
[4, 3, 2, 1, 5]

或者,也許更容易理解:

>>> lst = [1, 2, 3, 4, 5] 
>>> sl=lst[3::-1]
>>> lst[0:len(sl)]=sl
>>> lst
[4, 3, 2, 1, 5]

lst[::-1]是 Python 中反轉列表的慣用方式,以下顯示了它是如何就地的:

>>> lst = [1, 2, 3, 4, 5]
>>> id(lst)
12229328
>>> lst[:] = lst[::-1]
>>> lst
[5, 4, 3, 2, 1]
>>> id(lst)
12229328

嘗試一些crazy slicing ,請參閱解釋 Python 的切片符號http://docs.python.org/2.3/whatsnew/section-slices.html

x = [1,2,3,4,5,6,7,8]

def sublist_reverse(start_rev, end_rev, lst):
    return lst[:end_rev-1:start_rev-1]+lst[:[end_rev]

print sublist_reverse(0,4,x)

[出去]:

[8, 7, 6, 5, 4, 3, 2, 1]

我有兩種就地反轉的方法,簡單的方法是中途遍歷列表,將元素與相應的mirror-elements交換。 鏡像元素我的意思是 (first, last), (2nd, 2nd-last), (3rd, 3rd-last), 等等。

def reverse_list(A):
    for i in range(len(A) // 2): # half-way
        A[i], A[len(A) - i - 1] = A[len(A) - i - 1], A[i] #swap
    return A

另一種方式與上述類似,但使用遞歸而不是“循環”:

def reverse_list(A):
    def rev(A, start, stop):
        A[start], A[stop] = A[stop], A[start] # swap
        if stop - start > 1: # until halfway
            rev(A, start + 1, stop - 1)
        return A

    return rev(A, 0, len(A) - 1)

不確定您是否有與我類似的問題,但我需要原地反轉列表。

我唯一缺少的是[:]

exStr = "String"

def change(var):
  var[:] = var[::-1] # This line here

print(exStr) #"String"
change(exStr)
print(exStr) #"gnirtS"

我進行了一個小實驗,似乎對 list slice 的任何分配都會導致內存分配:

import resource
resource.setrlimit(resource.RLIMIT_AS, (64 * 1024, 64 * 1024))

try:
    # Python 2
    zrange = xrange
    arr_size = 3 * 1024
except NameError:
    # Python 3
    zrange = range
    arr_size = 4 * 1024

arr = list(zrange(arr_size))

# We could allocate additional 100 integers, so there should be enough free memory
# to allocate a couple of variables for indexes in the statement below
#   additional_memory = list(zrange(100))

# MemoryError is raised here
arr[:] = zrange(arr_size)

所以你必須使用 for 循環來反轉子列表。

PS:如果你想重復這個測試,你應該確保setrlimit RLIMIT_AS在你的平台上正常工作。 此外, arr_size可能因不同的 Python 實現而異。

兩種方法就地和常量內存:

def reverse_swap(arr, start=None, end=None):
    """
    Swap two edge pointers until meeting in the center.
    """

    if start is None:
        start = 0
    if end is None:
        end = len(arr)

    i = start
    j = end - 1
    while i < j:
        arr[i], arr[j] = arr[j], arr[i]
        i += 1
        j -= 1

def reverse_slice(arr, start=None, end=None):
    """
    Use python slice assignment but use a generator on the right-hand-side
    instead of slice notation to prevent allocating another list.
    """

    if start is None:
        start = 0
    if end is None:
        end = len(arr)

    arr[start:end] = (arr[i] for i in range(end - 1, start - 1, -1))

最簡單的方法可能是使用切片賦值和reversed()

lst[start:end] = reversed(lst[start:end])

您也可以同時切片和反轉,但這通常需要使用負索引或在start = 0時專門處理這種情況,即:

lst[start:end] = lst[end-len(lst)-1:start-len(lst)-1:-1]

或者

 lst[start:end] = lst[end-1::-1] if start == 0 else lst[end-1:start-1:-1]

OTOH,單獨使用切片比reversed()解決方案更快

更干凈的方法來做到這一點

a = [1,2,3,4,5,6,7,8,9]
i = 2
j = 7
while (i<j):
   a[i],a[j]=a[j],a[i]
   j -= 1
   i += 1
print(a)
lst = [1,2,3,4,5,6,7,8]

假設您必須原地將第 2 個位置反轉到第 4 個位置。

lst[2:5] = lst[2:5][::-1]

輸出:

[1,2,5,4,3,6,7,8]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM