P105: Reverse a list
颠倒列表。用单元测试描述为:
from python99.lists.p105 import reverse, reverse_recursively
def test_reverse():
input = [1, 2, 3, 4, 5, 6]
actual = reverse(input)
assert actual == None
assert input == [6, 5, 4, 3, 2, 1]
Python内建的数据类型list
提供了方法reverse()
,用于颠倒list
中的元素。但reserve()
是写操作。其会直接改变list
对象里面的元素位置,而非生成一个新的元素位置相反的list
。
## Reverse a list
def reverse(list):
if list is None:
return []
return list.reverse()
The Python Standard Library >> Sequence Types -- list, tuple, range
如何实现一个祇读的颠倒列表方法呢?
没有什么问题是递归解决不了的!
一个列表可被拆分为第一个元素和剩余列表。假如剩余列表已经被颠倒了,则祇需将拆分出来的第一个元素和剩余列表位置颠倒。颠倒两个物体的位置其实就是交换位置。但问题来了,如何颠倒剩余列表呢?继续拆分,直至剩余列表为空。空列表颠倒前跟颠倒后是一模一样的。
举个例子,给定一个列表[ a, b, c, d, e ]
。
- 将其拆分为第一个元素
a
和剩余列表[ b, c, d, e ]
- 继续将剩余列表拆分为第一个元素
b
和剩余列表[ c, d, e ]
- 继续拆分为
c
和[ d, e ]
- 继续拆分为
d
和[ e ]
- 颠倒
d
和[ e ]
的位置 - 合併
d
和[ e ]
为一个列表[ e, d ]
- 颠倒
c
和[ e, d ]
的位置 - 合併
c
和[ e, d ]
为一个列表[ e, d, c ]
- 颠倒
b
和[ e, d, c ]
的位置 - 合併
b
和[ e, d, c ]
为一个列表[ e, d, c, b ]
- 颠倒
a
和[ e, d, c, b ]
的位置 - 合併
a
和[ e, d, c, b ]
为一个列表[ e, d, c, b, a ]
代码实现:
def reverse_recursively(l):
if l == []:
return l
return reverse_recursively(l[1:]) + [l[0]]
单元测试:
def test_reverse_immutable():
assert reverse_recursively([1, 2, 3, 4, 5, 6]) == [6, 5, 4, 3, 2, 1]