![Python数据整理](https://wfqqreader-1252317822.image.myqcloud.com/cover/51/32436051/b_32436051.jpg)
练习17:使用用户定义的方法实现栈
我们将继续上个练习中的栈主题。但这个练习中我们将自己实现append和pop函数。这个练习的目的有两个:一方面,我们将用实际生活中的一个例子实现这个栈,这个例子还涉及字符串方法的知识,因此可以作为上一章内容和活动的重温;另一方面,它将向我们展示Python的一个微妙特性,以及它如何将列表变量传递给函数,并将带我们进入下一个练习,函数编程。
1.首先定义两个函数:stack_push和stack_pop。我们对它们进行了重命名,这样就不会发生名称空间之间的冲突。另外,创建一个名为url_stack的栈供以后使用:
![](https://epubservercos.yuewen.com/63BD11/17517093106688706/epubprivate/OEBPS/Images/027-i.jpg?sign=1739313339-Mzu3zGOu2FUsvifLEj9O6FwpL6P0eSye-0-ba9828a9304916c2dd9a6c8cc79bae12)
2.第一个函数获取已经存在的栈,并在其末尾添加值。
说明
注意value周围的方括号,为了+操作,它将其转换为只有一个元素的列表。
3.第二个函数读取当前位于栈的-1索引处的值,然后使用del运算符删除该索引,最后返回先前读取的值。
4.现在我们有一串包含几个URL的字符串。我们的工作是分析该字符串,以便在遇到栈中的URL时逐个推送它们,最后使用for循环逐个弹出它们。让我们从维基百科中关于数据科学的文章开始:
![](https://epubservercos.yuewen.com/63BD11/17517093106688706/epubprivate/OEBPS/Images/027-2-i.jpg?sign=1739313339-6sUybtgultIBZB5NIRyUxCMFfpbzkesA-0-f80bd5870ee14dbcadfb4cc36addc507)
5.为了简化这个练习,我们将目标单词之外的链接用方括号括了起来。
6.查找字符串的长度:
![](https://epubservercos.yuewen.com/63BD11/17517093106688706/epubprivate/OEBPS/Images/027-3-i.jpg?sign=1739313339-mAzSzPEEqlGMsJwUVNnkNN9c2565n0Q8-0-889d419448faf38771ee75d271a57d38)
输出如下:
![](https://epubservercos.yuewen.com/63BD11/17517093106688706/epubprivate/OEBPS/Images/027-4-i.jpg?sign=1739313339-sOW0k4WTaDuoZkPG7VJneXO6pkZBNXq8-0-ee439daeb9c99ac8e57d75a0f09ed339)
7.使用字符串中的split方法将此字符串转换为列表,然后计算其长度:
![](https://epubservercos.yuewen.com/63BD11/17517093106688706/epubprivate/OEBPS/Images/027-5-i.jpg?sign=1739313339-k4tiF9V2sNarjcuODrHkoQQweZ0rAIWo-0-4e53b15f7daec74f9078db77cf4e980b)
输出如下:
![](https://epubservercos.yuewen.com/63BD11/17517093106688706/epubprivate/OEBPS/Images/027-6-i.jpg?sign=1739313339-RzexJ7RBN3Tpl9G4pzVp23MdNCIeV53Y-0-ce7d5e0343e96da0ecace0db5df39c64)
8.使用for循环遍历每个单词并检查它是否是URL。为此,我们将使用字符串中的startswith方法,如果它是URL,则将其推入栈:
![](https://epubservercos.yuewen.com/63BD11/17517093106688706/epubprivate/OEBPS/Images/028-i.jpg?sign=1739313339-N5ykBoK9xvHhTrgVKgACMqTdP3IUWHja-0-d96fe3afbc61e5578919423f7fd0b082)
9.输出url_stack中的值:
![](https://epubservercos.yuewen.com/63BD11/17517093106688706/epubprivate/OEBPS/Images/028-2-i.jpg?sign=1739313339-YxsKMKjDd1Db4Xz6ZSv2NcuRMQGDUqOk-0-4a3af93499a0f99a1a621dccb8a692b5)
输出如下:
![](https://epubservercos.yuewen.com/63BD11/17517093106688706/epubprivate/OEBPS/Images/028-3-i.jpg?sign=1739313339-IEwGcFsisXEdyauNeqTlMhqskEoAfBfq-0-7db0dd7da8b75201a8fdf0f95e35ab60)
10.迭代列表并使用stack_pop函数逐个打印URL:
![](https://epubservercos.yuewen.com/63BD11/17517093106688706/epubprivate/OEBPS/Images/028-4-i.jpg?sign=1739313339-zHle7NAqip0UBYxmC6jNCq3ikubGF8FA-0-3a8ea06bfb5688d54e4ac91a9c3b7678)
输出如图2-2所示。
![](https://epubservercos.yuewen.com/63BD11/17517093106688706/epubprivate/OEBPS/Images/t2-2.jpg?sign=1739313339-HGaiSbS6KmAF7xd0PV1gtseiEzMCVQMn-0-dad5c1f423155d6d6a308e8c28912f78)
图2-2 使用栈输出的URL
11.再次打印以确保在for循环之后栈为空:
![](https://epubservercos.yuewen.com/63BD11/17517093106688706/epubprivate/OEBPS/Images/028-5-i.jpg?sign=1739313339-irOcq63wjeHZBePTsPDSNF6ntXFJ9cPR-0-74d9922769466f3942a546350599bd05)
输出如下:
![](https://epubservercos.yuewen.com/63BD11/17517093106688706/epubprivate/OEBPS/Images/028-6-i.jpg?sign=1739313339-o6C2sw2fFEreQmRJegymGTaHwgLqNkGw-0-918d2881beef377b9a20fec70416fa16)
我们注意到stack_pop方法中有一个奇怪的现象。我们在这里传递了列表变量,并在函数内部使用了del运算符,但是每次调用函数时,它都会删除最后一个索引,从而改变了原始变量。如果你熟悉C语言、C++语言和Java语言,那么这是一个完全出乎意料的行为。在这些语言中,只有当我们通过引用传递变量时这些行为才会发生,而且它能在Python代码中引起微小的错误,所以要小心。通常,在函数内部改变一个变量的值并不是一个好主意。传递给函数的任何变量都应该被认为是不可变的,这接近于函数式编程的原理。Python中的Lambda表达式是一种构造单行无名称函数的方法,这些函数按照约定是无副作用的。