我想通过使用堆栈数据结构而不使用递归来反转字符串
<块引用>str= 我们击败了 Corona
<块引用>reversed str = anoroC detaefed ew
from collections import deque
class Stack:
def __init__(self):
self.container = deque()
def rev(self):
nstk= deque()
for i in self.container(len(self.container),0,-1):
nstk.append(i)
return nstk
def push(self,val):
self.container.append(val)
def peek(self):
return self.container
st = Stack()
lst= list('we defeated Corona')
st.push(lst)
print(st.peek())
revStack= st.rev()
print(revStack)
为什么我不能使用下面的代码来反转...
def rev(self):
self.container.reverse()
答案 0 :(得分:0)
假设您有一个名为“CookieJar
”的容器类
CookieJar
有一个名为 insert()
假设我们执行以下代码:
cj = CookieJar()
# [some time later...]
output = cj.insert("new cookie")
cj
是否与调用 insert()
方法之前相同?output
中究竟存储了什么?在计算机编程中,有两种方法可以修改 cookie jar 的内容:
范式的正式名称 | 改变输入 | 输出 |
---|---|---|
[未知名称] | 保留输入的 cookie jar。 | 输出cookie jar的修改副本 |
就地修改 | 修改原来的cookie jar | 在python中,输出None 。在 Python 以外的语言(Java、C# 等)中,这将被称为“void 返回方法” |
计算机程序员最常犯的错误之一是他们认为修改器会返回容器的修改副本。
from collections import deque
my_deque = deque()
my_deque.appendleft("a")
my_deque.appendleft("b")
my_deque.appendleft("c")
print(my_deque)
output = my_deque.reverse()
print(output)
# output == None
reverse()
类的 deque
方法就地修改 deques
。
reverse()
输出 None
txt = " kiwi "
print("BEFORE `rstrip` txt is: ", repr(txt))
# ABOUT RSTRIP():
# RSTRIP()` removes `\n`, `\r` `\t`, space, etc...
# from the right-hand side of the string
output = txt.rstrip()
print("output is:", repr(output))
print("AFTER EXECUTING `rstrip()`, txt is: ", repr(txt))
就地修改 | 返回修改后的副本 | |
---|---|---|
执行rstrip() 后,txt 会发生什么? |
txt 变成:" kiwi" |
txt 还是原来的" kiwi " |
rstrip() 返回的值是多少? |
返回值为None |
返回值为" kiwi" |
计算机程序员在选择使用哪种范式方面不一致。
来自 deque
库的 collections
类的 mutator 方法就地修改了 deque
。
字符串类 str
的 python mutator 方法,永远不要修改原始字符串。
答案 1 :(得分:0)
普通列表和普通函数
如果您只需要实现一个堆栈,我认为没有理由使用 collections.deque
。我们可以轻松地围绕一个简单的列表进行构建,[]
-
# stack.py
def empty():
return []
def push(t, x):
t.append(x)
def pop(t):
return t.pop()
def load(t, iterable):
for x in iterable:
push(t, x)
def unload(t):
while t:
yield pop(t)
使用堆栈很直观 -
# main.py
import stack
input = "we have not defeated corona"
s = stack.empty()
stack.load(s, input)
output = "".join(stack.unload(s))
print(output)
anoroc detaefed ton evah ew
让它感觉更像蟒蛇
如果你想让stack
更有面向对象的感觉,我们可以围绕普通函数添加一个接口-
# stack.py (continued)
class stack:
def empty(): return stack(empty())
def __init__(self, t): self.t = t
def push(self, v): return push(self.t, v)
def pop(self): return pop(self.t)
def load(self, iterable): return load(self.t, iterable)
def unload(self): return unload(self.t)
现在我们可以这样写main
-
# main.py
from stack import stack
input = "we have not defeated corona"
s = stack.empty()
s.load(input)
output = "".join(s.unload())
print(output)
anoroc detaefed ton evah ew
扩展堆栈模块
继续向 Stack 模块添加其他功能 -
# stack.py (continued)
def reverse(t):
t.reverse()
def peek(t):
if not t:
return None
else:
return t[-1]
将您的新功能包装在面向对象的界面中 -
# stack.py (continued)
class stack:
def empty(): ...
def __init__(): ...
def push(): ...
def pop(): ...
def load(): ...
def unload(): ...
def reverse(self): return reverse(self.t) # <-
def peek(self): return peek(self.t) # <-
让我们验证 seek
和 reverse
工作 -
# main.py
from stack import stack
input = "we have not defeated corona"
s = stack.empty()
s.load(input)
print(s.peek())
s.pop()
print(s.peek())
s.reverse()
print(s.peek())
a
n
w
相关阅读
在 recent Q&A 中,我展示了如何设计类似于上面 stack
的模块。如果您想了解随着程序的发展如何应用这种技术,我鼓励您查看该帖子 :D
持久堆栈
作为一个有趣的练习,我们可以在不使用 deque
、list
或任何其他内置数据容器的情况下实现堆栈。相反,我们将使用普通的 None
和匿名函数。我分享这个例子是为了让你意识到程序员可以在他们的想象中构建任何东西,即使你使用的语言不包含特定的功能 -
# stack.py
empty = None
def push(t, v):
return lambda k: k(t, v)
def pop(t):
if not t:
raise RuntimeError("cannot pop empty stack")
else:
return t(lambda next, v: (next, v))
def load(t, iterable):
for v in iterable:
t = push(t, v)
return t
def unload(t):
while t:
(next, v) = pop(t)
yield v
t = next
def reverse(t):
return load(empty, unload(t))
def peek(t):
if not t:
return None
else:
(_, v) = pop(t)
return v
class stack:
def empty(): return stack(empty)
def __init__(self, t): self.t = t
def push(self, v): return push(self.t, v)
def pop(self):
(next, v) = pop(self.t)
return (stack(next), v)
def load(self, iterable): return stack(load(self.t, iterable))
def unload(self): return unload(self.t)
def reverse(self): return stack(reverse(self.t))
def peek(self): return peek(self.t)
不是使用 .append
、.pop
或 .reverse
修改底层堆栈,而是每个堆栈操作都会创建一个新堆栈。请注意我们如何unload
堆栈两次(或更多),如果我们愿意 -
from stack import stack
input = "we have not defeated corona"
s = stack.empty().load(input)
print("".join(s.unload()))
print("".join(s.reverse().unload()))
print("".join(s.unload()))
anoroc detaefed ton evah ew
we have not defeated corona
anoroc detaefed ton evah ew