美文网首页
叶子带你学 Python | (三)更多变量类型

叶子带你学 Python | (三)更多变量类型

作者: 初心不变_叶子 | 来源:发表于2021-07-28 22:55 被阅读0次

    习题答案

    作业一:使用 while 循环结构,因为需要在有评论时执行回复操作,没有评论时什么也不做。使用while True形成一个死循环,然后在其中判断是否有新评论也是可行的,但考虑到运行效率,一般在实际场景中不这样编写程序。

    作业二:由于 if 语句和 elif 语句的顺序颠倒,在分数介于 0 到 60 之间时,本应该输出不及格,但由于这个区间的数符合小于 90 的条件,所以直接进入了第一个分支。

    正确代码如下:

    if score < 60:
        print("怎么会没及格呢?")
    elif score < 90:
        print("差一点就优秀了")
    else:
        print("优秀,继续加油!")
    

    作业三,代码如下:

    for i in range(100):
        i = 1 + 1
        if i % 2 == 0:
            print(i)
    

    这是使用当前学习到的知识可以编写的最优代码。

    另外,这样也是可以的,但涉及到 Python 的高阶语法,暂且不做讲解,感兴趣的小伙伴可以尝试运行一下:

    [print(i) for i in range(1, 101) if i % 2 == 0]
    

    列表

    承接上文,你尝试着输出了 0 到 100 中所有的偶数,但新的问题接踵而至:怎么存储它们呢?

    难道要定义五十个变量?

    既然你有这个需求,Python 的开发者也一定有对应的解决方法:使用列表。

    列表也是一种变量,但它类似一个篮子,你可以在其中放入各种变量:布尔值、整数、浮点数、字符串,甚至另一个列表。

    空列表用一对中括号表示,让我们来试一下:

    a = []
    

    当然,你也可以在列表定义时就向里面加入一些东西:

    b = [True, 0, 666.66, "叶子", True]
    

    在每个英文逗号后加入空格也是一种编程规范,不遵守不会导致错误。

    注意不要把列表的名字定义成”list“,原因我们会在后文提到。

    你可能注意到了,列表中的内容是可以重复的。

    创建列表之后也可以向里面加入东西,代码如下:

    a.append(False)
    

    以上代码中,我们向刚刚创建的新列表中加入了一个布尔值 False,它将出现在列表末尾。

    有增肯定有减,我们可以使用 remove() 函数从列表里删除内容:

    b.remove(True)
    print(b)
    

    输出是[0, 666.66, '叶子', True]。由此可见,当你要删除的元素在列表中不止一个时,只有第一个元素会被删除。

    你也可以输出列表中的每一项,使用 for 循环:

    for i in b:
        print(i)
    

    到这里,我们就可以解释 for 循环的工作原理了:每次循环开始前,从 in 后的列表中拿出一项,将其赋值给循环变量(在这里是 i)。

    range() 函数也可以这样理解,它接收一个整数,生成由 0 到 n-1 中所有整数组成的列表。

    现在思考一下,如果我们要从列表中查找一个特定的值,找到则输出 True,否则输出 False,应该如何实现呢?

    是这样吗?

    for i in b:
        if i == "叶子":
            print(True)
        else:
            print(False)
    

    可以实现,但好像有些复杂了。

    其实 Python 提供了一种简便的方法:使用 in 来判断一个元素是否在列表中:

    if "叶子" in b:
        print(True)
    else:
        print(False)
    

    这里的 in 被叫做成员运算符,有点像从队伍里找人,也就是判断一个人是不是这个队伍里的”成员“。

    既然说到了队伍,现在有人想要知道队伍里由多少人,该怎么办呢?

    难道是这样?

    sum = 0
    
    for i in b:
        sum = sum + 1
        
    print(sum)
    

    不,最好这样:

    print(len(b))
    

    len() 也是一个函数,它是英语中”length“的缩写,意为”长度“。

    它的参数是一个列表,返回一个整数,代表这个列表中的元素个数。

    这样做还有一个优点:当列表特别大时,使用 len() 函数获取元素个数比 for 循环要快得多,因为这是一个非常常用的操作,Python 对其进行了优化。

    元组

    这个词可能听起来有些陌生,它是一个不可变的列表。

    列表,还不可变,这东西由什么用呢?我第一次看到它时也是这么想的。

    在叙述它的用途之前,先来说说如何使用它。

    c = ()
    

    其实就是把列表的中括号换成了小括号。

    注意,当元组里只有一个元素时,需要在这个元素的后面加上一个逗号,就像这样:

    d = (1, )
    

    但是,你不能对它进行任何改变,如果你尝试使用 append() 函数:

    AttributeError: 'tuple' object has no attribute 'append'
    

    这个错误信息告诉你它不能进行添加操作。同理,删除也不可以。

    当然,你可以使用 len() 函数获取它其中的元素个数。

    简单说一下元组相较于列表的优点:它的创建速度更快,而且占用内存空间更小。在一般的程序中,这两点并不会有决定性的意义,但当你要处理数万规模的、不会被改变的数据时,元组就派上用场了。

    另外,虽然它本身不能被改变,但你可以在它其中嵌套一个列表,然后改变这个列表中的值。

    但列表在元组里,我们怎么改变它呢?

    索引

    这个名词又是什么意思?

    其实可以类比成队伍里一个人的位置,小明在第 1 个,小刚在第 2 位......

    我们可以在一个列表或元组后加上一个中括号,其中填入一个整数,来获取对应位置的元素。

    b = [True, 0, 666.66, "叶子", True]
    print(b[1])
    

    咦?输出结果为什么是 ”0“ 而不是 ”True“?

    这是因为在列表和元组中,索引是从 0 开始的。现在你可以理解为什么 range() 函数生成的列表从 0 开始了吧。

    所以,想要取第一个值应该这样做。

    print(b[0])
    

    最后一个值呢?当然可以用 len() 获取列表中的元素个数再进行处理,但有更简便的方法:

    print(b[-1])
    

    -1 就是倒数第一个,-2 是倒数第二个,以此类推,是不是简单多了?

    可以用一张图来直观展示列表中值与对应索引的关系:

    image

    这个简单的图表也是用 Python 生成的,代码实现可以暂时忽略。

    切片

    简单理解,就是从列表或者元组里取一部分。

    一直说”列表和元组“有点麻烦,干脆给这些变量取个名字,就叫”可迭代对象“好了,因为它们都可以用 for 循环进行迭代,也就是把里面的元素依次拿出来使用。

    切片的语法很简单,但其中有几个坑需要我们注意:

    b = [True, 0, 666.66, "叶子", True]
    print(b[2:4])
    

    猜猜这段代码输出什么?是[666.66, '叶子'],第三个和第四个元素。

    因为切片是左闭右开的,也就是说包含开始的那个元素,但不包含结束的那个元素,是不是有点像 range()?

    所以,按照索引为 0 的规则,从索引 2 开始,取 2 和 3,不取 4。

    如果我偷个懒,只写切片开始的位置,不写结束的位置,或者反过来,会发生什么?

    b = [True, 0, 666.66, "叶子", True]
    print(b[2:])
    print(b[:4])
    

    以下是输出结果:

    [666.66, '叶子', True]
    [True, 0, 666.66, '叶子']
    

    可以看出,不写开始位置时,默认从开头开始取,等效于开始位置写 0;不写结束位置时,默认取到结尾,等效于结束位置写len() + 1

    现在我们来极致偷个懒,开头结尾都不写:

    b = [True, 0, 666.66, "叶子", True]
    print(b[:])
    

    大家可能已经猜到了,输出结果和 b 一模一样,也就是说,在开头结尾都不写的情况下,输出原列表。

    但事实上现在输出的列表,和原先的列表 b 已经没有了任何关系,只是它们含有的元素完全相同罢了。

    所以,如果你使用==进行比较,它们是相等的,但如果改变其中一个的值,另一个不会一起改变。

    这涉及到深拷贝和浅拷贝的问题,我们暂且略过。

    字典

    对,就是大家平时用的那个字典。

    想想我们是怎么查字典的,以英汉字典为例:先找到单词首字母对应的位置,然后找到单词,一个单词可能有多个中文含义。

    在 Python 里面,我们把查字典所寻找的单词叫做”键“,把中文含义叫做”值“。

    键是不可变的,但值可变;一个键可以对应多个值。

    说到不可变,看看前面的内容,想到了什么?是的,元组可以做字典的键,但列表不可以。

    注意,如果使用元组作为字典的键,这个元组中不能含有列表,必须保证它其中的所有元素都不可变。

    我们使用大括号来创建一个列表,键和值之间用引号隔开,每一项之间用逗号分隔:

    article = {
        "title": "叶子带你学 Python", 
        "reads_count": 666, 
        "likes_count": 50, 
        "fp_amount": 88.88
    }
    

    现在我们要查字典了,如果我想获取文章标题,可以这样做:

    print(article[title])
    

    其实就是把列表的索引换成了字典的键。

    在字典中添加一项,可以这样:

    article["author"] = "初心不变_叶子"
    

    是不是有点像定义变量?顺便说一句,你也可以用类似的方式修改列表中特定位置的值。

    对字典中值的删除并不是使用 remove(),具体方法我们会在后文讲到。

    其实,字典还有三个非常有用的函数,分别是keys()values()items(),让我们来试试:

    print(article.keys())
    print(article.values())
    print(article.items())
    

    输出结果:

    dict_keys(['title', 'reads_count', 'likes_count', 'fp_amount'])
    dict_values(['叶子带你学 Python', 666, 50, 88.88])
    dict_items([('title', '叶子带你学 Python'), ('reads_count', 666), ('likes_count', 50), ('fp_amount', 88.88)])
    

    好像有些奇怪,但可以大体看出,前两个函数输出列表,分别是字典中所有的键和所有的值。

    第三个函数输出的也是一个列表,但在列表中是一个个元组,分别代表字典中的键和它们所对应的值。

    事实上,这些输出不是真正的列表,而是一些对象,只不过它们的操作和列表的操作几乎一致。

    简单说一下字典的优点:它是 Python 中实现键值查找的最简单方式,同时由于它的使用场景,其查找速度极快,且不会因为字典中元素的增多而变慢。

    课后作业

    这篇文章中,我们学习了 Python 中三种最常用的、可以包含其它变量的变量类型。事实上,它们的专业叫法是”数据类型“,因为这些变量本质上都是有名字的数据。

    作业一:请问元组里可以嵌套列表吗?

    作业二:指出以下程序中的错误(共有 3 处):

    a = [1, 2, 3. 4]
    b = (True)
    for i in a:
        if i in b == False:
            b.append(i)
    

    作业三:给定以下列表:

    a = [1, 1, 2, 2, 2, 3, 3, 3, 4, 4]
    

    请编写程序,删除其中的所有偶数。

    提示:使用 if 和 % 操作符判断是否是偶数,注意 remove() 在列表中有多个待删除元素时的行为,可以使用成员操作符 in 判断是否仍有元素未被删除。

    相关文章

      网友评论

          本文标题:叶子带你学 Python | (三)更多变量类型

          本文链接:https://www.haomeiwen.com/subject/snvtvltx.html