簡體   English   中英

在不使用內置函數的情況下反轉列表

[英]Reverse a list without using built-in functions

我正在使用Python 3.5。

作為問題的一部分,我正在嘗試設計一個將列表作為輸入並將其還原的函數。 因此,如果x = [a, b, c]則函數將使x = [c, b, a]

問題是,我不允許使用任何內置函數,它讓我陷入困境。 我最初的想法是函數內的以下循環:

for revert in range(1, len(x) + 1):
    y.append(x[-revert])

它有效。 但問題是我使用len(x) ,我相信它是一個內置函數,對嗎?

所以我四處搜索並制作了以下非常簡單的代碼:

y = x[::-1]

這正是我想要的,但它看起來幾乎太簡單/容易,我不確定"::"是否算作一個函數。

所以我想知道是否有人有任何提示/想法如何手動設計所述功能? 當你不能使用任何內置函數時它看起來真的很難,現在我已經停留了很長時間。

rangelen都是內置函數 由於接受了list 方法 ,您可以使用insert執行此操作。 它實際上很慢 *但是它可以在不使用任何內置函數的情況下完成小型列表的工作:

def rev(l):
    r = []
    for i in l:
        r.insert(0, i)
    return r

通過連續插入第零個位置,您最終得到了輸入列表的反轉版本:

>>> print(rev([1, 2, 3, 4]))
[4, 3, 2, 1]

這樣做:

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

也可以被認為是一種解決方案。 ::-1::有不同的結果)不是一個函數(它是一個切片)而[]是一個列表方法。 此外,對比insert ,它更快,更可讀; 只要確保你能夠理解並解釋它。 在這個SO答案中可以找到關於它如何工作的一個很好的解釋

* Reeaaalllyyyy緩慢,看到juanpa.arrivillaga對於很酷的情節的回答,並append pop並在Yoav Glazner的回答中查看列表上的就地reverse

::不是函數,它是一個python文字 以及[]

如何檢查::, []是否為函數。 簡單,

    import dis
    a = [1,2]
    dis.dis(compile('a[::-1]', '', 'eval'))
      1           0 LOAD_NAME                0 (a)
                  3 LOAD_CONST               0 (None)
                  6 LOAD_CONST               0 (None)
                  9 LOAD_CONST               2 (-1)
                 12 BUILD_SLICE              3
                 15 BINARY_SUBSCR
                 16 RETURN_VALUE

如果::,[]是函數,則應在a[::-1]語句執行的python指令中找到標簽CALL_FUNCTION 所以,他們不是。

看一下調用函數時python指令的樣子,比如說list()函數

>>> dis.dis(compile('list()', '', 'eval'))
  1           0 LOAD_NAME                0 (list)
              3 CALL_FUNCTION            0
              6 RETURN_VALUE

所以,基本上

def rev(f):
    return f[::-1]

工作良好。 但是,我認為如果你的問題是家庭作業或由老師發送,你應該像Jim在答案中建議的那樣做。 但是,您可以添加這種最快的方式作為旁注。

如果老師抱怨[::-1]符號,請告訴他我給你的例子。

這是一個不使用內置函數但依賴於list方法的解決方案。 如您的規范所暗示的那樣,它就地反轉:

>>> x = [1,2,3,4]
>>> def reverse(seq):
...   temp = []
...   while seq:
...     temp.append(seq.pop())
...   seq[:] = temp
... 
>>> reverse(x)
>>> x
[4, 3, 2, 1]
>>> 

ETA

吉姆,你在0號位置使用insert的答案讓我瘋了! 那個解決方案是二次時間! 您可以使用appendpop臨時列表來使用簡單的列表方法實現線性時間。 請參閱( reverse為藍色, rev為綠色):

如果感覺有點像使用seq[:] = temp “作弊”,我們總是可以循環遍歷temp並將每個項目追加到seq ,時間復雜度仍然是線性的但可能更慢,因為它沒有使用C-基於內部。

另一種方式(僅為完整:))

def another_reverse(lst):
    new_lst = lst.copy() # make a copy if you don't want to ruin lst...
    new_lst.reverse() # notice! this will reverse it in place
    return new_lst

你的榜樣有效:

y = x[::-1]

使用Python 切片表示法 ,這是我假設您正在請求的意義上的功能。 基本上::充當分隔符。 更詳細的代碼版本是:

y = x[len(x):None:-1]

要么

y = x[start:end:step]

我可能不會抱怨python讓你的生活變得非常輕松。


編輯超級迂腐。 有人可能會說,調用[]根本就是使用內置的python函數,因為它實際上是方法__getitem__()語法糖。

x.__getitem__(0) == x[0]

而使用::確實使用了slice()對象。

x.__getitem__(slice(len(x), None, -1) == x[::-1]

但是......如果你要爭論這個,你在python中編寫的任何內容都將使用內置的python函數。

另一種完整性方法, range()采用可選的步驟參數,允許您在列表中向后退步:

def reverse_list(l):
    return [l[i] for i in range(len(l)-1, -1, -1)]

實現這一目標的最pythonic和有效方法是通過列表切片。 而且,既然你提到你不需要任何內置功能,它完全滿足你的要求。 例如:

>>> def reverse_list(list_obj):
...     return list_obj[::-1]
...
>>> reverse_list([1, 3, 5 , 3, 7])
[7, 3, 5, 3, 1]

只需從右到左迭代列表即可獲取項目..

a = [1,2,3,4]

def reverse_the_list(a):
   reversed_list = []
   for i in range(0, len(a)):
     reversed_list.append(a[len(a) - i - 1])
   return reversed_list

new_list = reverse_the_list(a)
print new_list

暫無
暫無

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

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