从头开始创建一个Python列表的反转方法

6

我想创建一个列表的反向方法。我知道Python已经内置了这样的方法,但我想尝试从头开始。这是我的代码,看起来对我来说很有道理,但它只返回相同顺序的列表。我的理解是列表是可变的,我可以在循环中重新分配值。

def reverse(data_list):
    length = len(data_list)
    s = length

    for item in data_list:
        s = s - 1
        data_list[s] = item
    return data_list
15个回答

15
def reverse(data_list):
    return data_list[::-1]
>> reverse([1,2,3,4,5])
[5, 4, 3, 2, 1]

切片方法对我很有效,谢谢。我觉得它有点困惑,但是在以下解释中找到了有用的信息(来源:https://www.geeksforgeeks.org/python-reversed-vs-1-which-one-is-faster/):“切片中的格式[a:b:c]表示从包含a到不包含b,以c为增量计数。在上面的代码中,a和b为空,c为-1。因此,它从最后一个元素向前迭代整个列表,结果是一个反转的列表。” - sebvargo

10

当你遍历列表的一半时,你已经交换了所有的项;当你继续遍历第二半部分时,你又将它们全部交换回原来的位置。

相反,尝试使用

def reverse(lst):
    i = 0            # first item
    j = len(lst)-1   # last item
    while i<j:
        lst[i],lst[j] = lst[j],lst[i]
        i += 1
        j -= 1
    return lst

这可以用两种方式:

a = [1,2,3,4,5]
reverse(a)        # in-place
print a           # -> [5,4,3,2,1]

b = reverse(a[:]) # return the result of reversing a copy of a
print a           # -> [5,4,3,2,1]
print b           # -> [1,2,3,4,5]

5

由于您在迭代列表(data_list)时更改了该列表,因此它无法正常工作,请尝试以下方法:

def reverse(data_list):
    length = len(data_list)
    s = length

    new_list = [None]*length

    for item in data_list:
        s = s - 1
        new_list[s] = item
    return new_list

谢谢!那个确实有效,但我的问题是[None]*length是什么意思?如果我把new_list设置为[]为什么不起作用? - user637965
2
[None]*length 会创建一个像这样的列表 [None, None ...],而 new_list = [] 不起作用,因为它会创建一个0元素的列表,所以当你尝试执行 new_lits[1] = .. 时,它会给出一个索引错误,因为列表中没有索引1,基本上 new_lits[1] = .. 会改变索引1的值为新值,而不是添加。希望这讲得通 :) - mouad
它失败的原因不是“因为你正在更改迭代的列表”; 只有在添加或删除列表项时才会出现此问题。它失败是因为每次交换都涉及两个位置(项和其双胞胎),因此到您处理整个列表的时间,您已经对每个项目进行了两次操作-交换它,然后将其交换回来。因此,每个项目最终都停留在起始位置。 - Hugh Bothwell

4

在Python中,一个简单的方法(不使用reverse函数)是使用[]访问运算符和负值,例如(打印并创建一个新的反向列表):

x = [1, 2 ,3, 4, 5]
newx = []
for i in range(1, len(x)+1):
  newx.append(x[-i])
  print x[-i]

该功能应该是:
def reverse(list):
  newlist = []
  for i in range(1, len(list)+1):
    newlist.append(list[-1])
  return newlist

1

当我尝试运行你的代码时,我得到的列表不同。但是我也没有得到一个反转的列表,因为列表是通过正在从末尾向后移动的列表状态进行更改的。我认为你想要做的方式是:

def reverse(data_set):
  length = len(data_set)

  for i in range(0, length / 2):
    length = length - 1
    hold = data_set[i]
    data_set[i] = data_set[length]
    data_set[length] = hold
  return data_set

这里我们实际上在一半的迭代中进行反转,并且我们记忆正在更改的索引的值,以便可以在同一步中设置“翻转”。


1
word_reversed = ''

    for i in range(len(word) -1, -1, -1):
        word_reversed += word[i]

这将翻转一个未知长度的字符串,称为(word),并将其命名为(word_reversed)。

我正在使用它来检查一个单词是否是回文,并且不允许使用 .reverse 或 word[::-1]。

# Tyler G
# April 10, 2018
# Palindromes

import re

word = input("Palindromes are words that spell the same thing forwars or backwards, enter a word and see if its one!: ")
word = word.lower()
word = re.sub("[^a-zA-Z]+", "", word)
# count the number of characters in the string
# make a if <string>[0] = <string[counted char -1]
# repeat that over and over
# make a else print("not a ...")
word_reversed = ''

for i in range(len(word) - 1, -1, -1):
    word_reversed += word[i]

itis = 0
if len(word) > 12:
    print("It is not a Palindrome")

else:
    for i in range(0, len(word)):
        if word[i] == word_reversed[i]:
            itis = itis + 1
        else:
            itis = itis - len(word)
    if itis > 0:
        print("It is a palindrome")
    else:
        print("It is NOT a Palindrome")

itis = 0
if len(word) > 12:
    print("It is not a Palindrome")

1

有两种简单的方法来解决这个问题: 第一种是使用临时变量:

maList = [2,5,67,8,99,34]
halfLen = len(maList) // 2
for index in range(halfLen):
    temp = maList[index]
    maList[index] = maList[len(maList) - 1 - index]
    maList[len(maList) - 1 - index] = temp
print(maList)

第二步是使用一个新的列表来存储反转后的值:
newList = []
for index,value in enumerate(maList):
    newList.append(maList[len(maList) - 1 - index])
print(newList)

0

类似这样的代码应该可以运行:

mylist = [1,2,3,4,5]
def reverse(orig_list):
    data_list = orig_list[:]
    length = len(data_list)
    for i in xrange(0, length/2):
        tmp = data_list[length-i-1]
        data_list[length-i-1] = data_list[i]
        data_list[i] = tmp
    return data_list

reverse(mylist)
mylist

0
不想创建一个新的列表来保存你的“temp”数据吗? 如果你看一下这个模式,它就很简单:
reverse_list([a, b, c, d, e]) => [e, d, c, b, a]

这意味着位置0 -> n1 -> (n - 1)2 -> (n - 2)。这意味着您可以弹出最后一个项目并将其放入当前索引...
def reverse_list(list):
    i = 0
    while i < (len(list) - 1):
        list.insert(i, list.pop())
        i += 1

你的回复应该是一个答案,但是你的帖子以提问开始。如果你提供了一个解决方案,请解释你的答案。如果你有问题,请在原始问题下面发表评论。 - jacefarm

0
def reverseOrder():
    my_list = []
    a = input("What is your word?")
    count = len(a) - 1


    x = ''
    for i in range(0, len(a)):
        my_list.append(a[count])
        count = count - 1
    x = x.join(my_list)
    print(x)

reverseOrder()

这是我的做法。首先我创建了一个空列表。然后我将用户的答案存储在一个变量中,并减去1以进行索引。现在开始一个for循环,将'range'从0到len(a)设置,然后从后向列表中添加元素,因为计数等于len(a)。之后你设置.join函数并将列表连接在一起。这就是为什么for循环之前有一个变量x的原因。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接