美文网首页Python自学教程
【Python 1-8】Python手把手教程之——管理列表Li

【Python 1-8】Python手把手教程之——管理列表Li

作者: 弗拉德x | 来源:发表于2020-11-27 11:56 被阅读0次

    作者 | 弗拉德
    来源 | 弗拉德(公众号:fulade_me)

    上一节我们学习了如何创建一个列表,在列表里面插入、删除数据等操作。
    本节我们学习如何管理列表。

    遍历列表

    在日常开发中,我们经常需要遍历列表的所有元素,对每个元素执行相同的操作。例如,在管理商场的蔬菜时候,需要给所有的蔬菜商品都打7折,并重新生成价格。当我们需要对列表中的每个元素都执行相同的操作时,可使用Python中的for循环。

    假设我们有一个蔬菜名单,需要将其中每种蔬菜的名字都打印出来。为此,我们可以采用元素下标的方式分别获取名单中的每个名字,但这种做法会导致多个问题。例如,如果名单很长,将包含大量重复的代码。另外,每当名单的长度发生变化时,都必须修改代码。通过使用for循环,可让Python去处理这些问题。
    下面使用for循环来打印蔬菜单中的所有名字:

    vegetables = ['potato','tomato','onion']
    for name in vegetables:
        print(name)
    

    这行代码让Python从列表vegetables中取出一个名字,并将其存储在变量name中。最后,我们让Python打印前面存储的变量name中的名字。这样,对于列表中的每个名字,Python都将重复执行print(name)代码。你可以这样解读这些代码:对于列表vegetables中的每种蔬菜,都将其名字打印出来。输出很简单,就是列表中所有蔬菜的姓名:

    potato
    tomato
    onion
    
    详解遍历列表执行过程

    循环这种概念很重要,因为它是让计算机自动完成重复工作的常见方式之一。例如,在前面的代码中使用的简单循环中,Python将首先读取其中的第一行代码:

    for name in vegetables:
    

    这行代码让Python获取列表vegetables中的第一个值potato,并将其存储到变量name 中。接下来,Python读取下一行代码:

    print(name) 
    

    它让Python打印vegetables的值potato。由于该列表还包含其他值,Python返回到循环的第一行:

    for name in vegetables:
    

    Python获取列表中的下一个名字tomato,并将其存储到变量name中,再执行下面这行代码:

    print(name) 
    

    Python再次打印变量vegetables的值tomato
    接下来,Python再次执行整个循环,对列表中的最后一个值onion进行处理。
    至此,列表中没有其他的值了,因此Python接着执行程序的下一行代码。在这个示例中,for循环后面没有其他的代码,因此程序就此结束。
    刚开始使用循环时需要牢记,对列表中的每个元素,都将执行循环指定的步骤,而不管列表包含多少个元素。如果列表包含一百万个元素,Python就重复执行指定的步骤一百万次,且通常速度非常快。
    另外,编写for循环时,对于用于存储列表中每个值的临时变量,可指定任何名称。比如说:

    for dog in dogs:
    for cat in cats:
    for item in item_list:
    

    这些写法都是可以的。

    在For循环中做更多操作

    在for循环中,可以获取到每一个元素,可对每个元素执行任何操作。比如说我们对每一种蔬菜都输出一句话。

    vegetables = ['potato','tomato','onion']
    for name in vegetables:
        print(name + ' is good !')
    

    相比于前一个示例,唯一的不同是对于每种蔬菜,都打印了一条以其名字为抬头的消息。这个循环第一次迭代时,变量name的值为potato,因此Python打印的第一条消息的抬头为potato。第二次迭代时,消息的抬头为tomato,而第三次迭代时,抬头为onion
    下面的输出表明,对于列表中的每种蔬菜,都打印了一条个性化消息:

    potato is good !
    tomato is good !
    onion is good !
    

    在for循环中,想包含多少行代码都可以。在代码行for name in vegetables后面,每个缩进的代码行都是循环的一部分,且将针对列表中的每个值都执行一次。因此,可对列表中的每个值执行任意次数的操作。
    下面再添加一行代码:

    vegetables = ['potato','tomato','onion']
    for name in vegetables:
        print(name + ' is good !')
        print(name + ' is a vegetable!')
    

    由于两条print语句都缩进了,因此它们都将针对列表中的每位蔬菜都执行一次。输出结果如下:

    potato is good !
    potato is a vegetable!
    tomato is good !
    tomato is a vegetable!
    onion is good !
    onion is a vegetable!
    

    for循环中,想包含多少行代码都可以。这种方式在开发过程中很有用。

    避免缩进错误

    Python根据缩进来判断代码行与前一个代码行的关系。在前面的示例中,对每种蔬菜的输出代码行是for循环的一部分,因为它们缩进了。Python通过使用缩进让代码更易读。
    简单地说,它要求你使用缩进让代码整洁而结构清晰。在较长的Python程序中,你将看到缩进程度各不相同的代码块,这让你对程序的组织结构有大致的认识。 当你开始使用缩进时,需要注意一些常见的缩进错误。
    例如,有时候,程序员会将不需要缩进的代码块缩进,而对于必须缩进的代码块却忘了缩进。通过查看这些错误示例,有助于我们以后避开它们,以及在它们出现在程序中时进行修复。下面来看一些较为常见的缩进错误。

    忘记缩进

    对于位于for语句后面且属于循环组成部分的代码行,一定要缩进。如果你忘记缩进,运行会直接报错:

    vegetables = ['potato','tomato','onion']
    for name in vegetables:
    print(name)
    

    print语句应缩进却没有缩进。Python没有找到期望缩进的代码块时,会让你知道哪行代码有问题。

     File "<stdin>", line 2
        print(name)
            ^
    IndentationError: expected an indented block
    

    通常,将紧跟在for语句后面的代码行缩进,可消除这种缩进错误。

    忘记缩进额外的代码行

    有时候,循环能够运行而不会报告错误,但结果可能会出乎意料。试图在循环中执行多项任务,却忘记缩进其中的一些代码行时,就会出现这种情况。

    vegetables = ['potato','tomato','onion']
    for name in vegetables:
        print(name + ' is good !')
    print(name + ' is a vegetable!')
    

    第二个print语句原本需要缩进,但Python发现for语句后面有一行代码是缩进的,因此它没有报告错误。最终的结果是,对于列表中的每种蔬菜,都执行了第一条print语句,因为它缩进了;而第二条print语句没有缩进,因此它只在循环结束后执行一次。由于变量 name 的终值为onion,因此只有一条输出了onion is a vegetable!:

    potato is good !
    tomato is good !
    onion is good !
    onion is a vegetable!
    

    这是一个逻辑错误。从语法上看,这些代码是没问题的,但由于存在逻辑错误,结果并不符合预期。如果你预期某项操作将针对每个列表元素都执行一次,但它却只执行了一次,请确定是否需要将一行或多行代码缩进。

    不必要的缩进

    如果你不小心缩进了无需缩进的代码行,同样运行的时候也会报错:

    message = "Hello Python world!"
        print(message)
    

    print语句无需缩进,因为它并不属于前一行代码,运行的时候会帮我们指出这种错误:

        print(message)
        ^
    IndentationError: unexpected indent
    

    为避免意外缩进错误,请只缩进需要缩进的代码。在前面编写的程序中,只有要在for循环中对每个元素执行的代码就需要缩进。

    循环后不必要的缩进

    如果我们不小心缩进了应在循环结束后执行的代码,这些代码将针对每个列表元素重复执行。 在有些情况下,这可能导致Python报告语法错误,但在大多数情况下,这只会导致逻辑错误。例如:

    vegetables = ['potato','tomato','onion']
    for name in vegetables:
        print(name + ' is good !')
        print(name + ' is a vegetable!')
        ## 这一行代码被缩进
        print('There are three kinds of vegetables.')
    

    那么输出就会变成以下这个样子:

    potato is good !
    potato is a vegetable!
    There are three kinds of vegetables
    tomato is good !
    tomato is a vegetable!
    There are three kinds of vegetables
    onion is good !
    onion is a vegetable!
    There are three kinds of vegetables.
    

    这也是一个逻辑错误。Python不知道你的本意,只要代码符合语法,它就会运行。所以我们应该时刻保持警惕,不要用错了缩进。

    遗漏了冒号

    for语句末尾的冒号告诉Python,下一行是循环的第一行。

    vegetables = ['potato','tomato','onion']
    for name in vegetables
        print(name + ' is good !')
    
    
        for name in vegetables
                             ^
    SyntaxError: invalid syntax
    

    如果你不小心遗漏了冒号,如上所示,将导致语法错误,因为Python不知道你意欲何为。这种错误虽然易于消除,但并不那么容易发现。

    数值列表

    Python函数range()让你能够轻松地生成一系列的数字。例如,可以像下面这样使用函数range()来打印一系列的数字:

    for value in range(1,5):
        print(value)
    

    上述代码好像应该打印数字1~5,但实际上它不会打印数字5:

    1
    2
    3
    4
    

    在这个示例中,range()只是打印数字1~4,这是你在编程语言中经常看到的差一行为的结果。函数range()让Python从你指定的第一个值开始数,并在到达你指定的第二个值后停止,因此输出不包含第二个值(这里为5)。
    要打印数字1~5,需要使用range(1,6):

    for value in range(1,6):
        print(value)
    

    这样,输出将从1开始,到5结束:

    1
    2
    3
    4
    5
    

    使用range()时,如果输出不符合预期,请尝试将指定的值加1或减1

    使用range()创建数字列表

    要创建数字列表,可使用函数list()range()的结果直接转换为列表。如果将range()作为list()的参数,输出将为一个数字列表。
    在上面的示例中,我们打印了一系列数字。要将这些数字转换为一个列表,可使用list():

    numbers = list(range(1,6))
    print(numbers)
    

    结果如下:

    [1, 2, 3, 4, 5]
    

    使用函数range()时,还可指定步长。例如,下面的代码打印1~10内的偶数:

    even_numbers = list(range(2,11,2)) 
    print(even_numbers)
    

    在这个示例中,函数range()从2开始数,然后不断地加2,直到达到或超过终值(11),因此 输出如下:

    [2, 4, 6, 8, 10]
    

    使用函数range()几乎能够创建任何需要的数字集,例如,如何创建一个列表,其中包含前10个整数(即1~10)的平方呢?在Python中,两个星号**表示乘方运算。下面的代码演示如何将前10个整数的平方加入到一个列表中:

    squares = []
    for value in range(1,11):
        square = value**2
        squares.append(square)
    print(squares)
    

    首先,我们创建了一个空列表;接下来,使用函数range()让Python遍历1~10的值。在循环中,计算当前值的平方,并将结果存储到变量square中。然后,将新计算得到的平方值附加到列表squares末尾。最后,循环结束后,打印列表squares:

    [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
    
    对数字列表执行简单的统计计算

    有几个专门用于处理数字列表的Python函数。例如,你可以轻松地找出数字列表的最大值、最小值和总和:

    digits = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] 
    ### 输出最小值
    print(min(digits))
    ### 输出最大值
    print(max(digits))
    ### 计算总和
    print(sum(digits))
    0
    9
    45
    
    列表解析

    列表解析将for循环和创建新元素的代码合并成一行,并自动附加新元素。下面的示例使用列表解析创建你在前面看到的平方数列表:

    squares = [value**2 for value in range(1,11)] 
    print(squares)
    

    要使用这种语法,首先指定一个描述性的列表名,如squares;然后,指定一个左方括号,并定义一个表达式,用于生成你要存储到列表中的值。在这个示例中,表达式为value**2,它来计算平方值。接下来,编写一个for循环,用于给表达式提供值,再加上右方括号。在这个示例中,for循环为for value in range(1,11),它将值1~10提供给表达式value**2。请注意,这里的for语句末尾没有冒号。
    结果与你在前面看到的平方数列表相同:

    [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
    

    要创建自己的列表解析,需要经过一定的练习,但能够熟练地创建常规列表后,你会发现这样做是完全值得的。当你觉得编写三四行代码来生成列表有点繁复时,就应考虑创建列表解析了。

    列表中的一部分

    在上面的内容中,我们学习了如何访问单个列表元素。接下来,我们将学习如何处理列表的所有元素。我们还可以处理列表的部分元素——Python称之为切片

    切片

    要创建切片,可指定要使用的第一个元素和最后一个元素的索引。与函数range()一样,Python 在到达你指定的第二个索引前面的元素后停止。要输出列表中的前三个元素,需要指定索引0~3, 这将输出分别为0、1和2的元素。
    我们还是以蔬菜列表为例:

    vegetables = ['potato','tomato','onion','leek']
    print(vegetables[0:3])
    

    上面的代码打印该列表的一个切片,其中只包含三种蔬菜。输出也是一个列表,其中包含前三种蔬菜:

    ['potato', 'tomato', 'onion']
    

    你可以生成列表的任何子集,例如,如果你要提取列表的第2~4个元素,可将起始索引指定为1,并将终止索引指定为4:

    vegetables = ['potato','tomato','onion','leek']
    print(vegetables[1:4])
    

    这一次,切片始于tomato,终于leek:

    ['tomato', 'onion', 'leek']
    

    如果你没有指定第一个索引,Python将自动从列表开头开始:

    vegetables = ['potato','tomato','onion','leek']
    print(vegetables[:4])
    

    由于没有指定起始索引,Python从列表开头开始提取:

    ['potato', 'tomato', 'onion', 'leek']
    

    要让切片终止于列表末尾,也可使用类似的语法。例如,如果要提取从第3个元素到列表末 尾的所有元素,可将起始索引指定为2,并省略终止索引:

    vegetables = ['potato','tomato','onion','leek']
    print(vegetables[2:])
    

    Python将返回从第3个元素到列表末尾的所有元素:

    ['onion', 'leek']
    

    无论列表多长,这种语法都能够让你输出从特定位置到列表末尾的所有元素。前面我们了解过,负数索引返回离列表末尾相应距离的元素,因此你可以输出列表末尾的任何切片。例如,如果你要输出名单上的最后三种蔬菜,可使用切片vegetables[-3:]:

    vegetables = ['potato','tomato','onion','leek']
    print(vegetables[-3:])
    ['tomato', 'onion', 'leek']
    
    遍历切片

    如果要遍历列表的部分元素,可在for循环中使用切片。在下面的示例中,我们遍历前三种蔬菜,并打印它们的名字:

    vegetables = ['potato','tomato','onion','leek']
    print("Here are the first three vegetable:")
    for name in vegetables[:3]:
        print(name.title())
    

    输出结果:

    Here are the first three vegetable:
    Potato
    Tomato
    Onion
    

    在很多情况下,切片都很有用。例如,编写游戏时,你可以在玩家退出游戏时将其最终得分加入到一个列表中。然后,为获取该玩家的三个最高得分,你可以将该列表按降序排列,再创建一个只包含前三个得分的切片。处理数据时,可使用切片来进行批量处理;编写Web应用程序时,可使用切片来分页显示信息,并在每页显示数量合适的信息。

    复制列表

    我们经常需要根据既有列表创建全新的列表。下面来介绍复制列表的工作原理,以及复制列表可提供极大帮助。
    要复制列表,可创建一个包含整个列表的切片,方法是同时省略起始索引和终止索引([:])。 这让Python创建一个始于第一个元素,终止于最后一个元素的切片,即复制整个列表。
    例如,假设有一个列表,其中包含你最喜欢的四种食品,而你还想创建另一个列表,在其中包含一位朋友喜欢的所有食品。不过,你喜欢的食品,这位朋友都喜欢,因此你可以通过复制来创建这个列表:

    my_foods = ['pizza', 'falafel', 'carrot cake'] friend_foods = my_foods[:]
    print("My favorite foods are:") 
    print(my_foods)
    print("\nMy friend's favorite foods are:") 
    print(friend_foods)
    

    我们首先创建了一个名为my_foods的食品列表,然后创建了一个名为friend_foods的新列表。我们在不指定任何索引的情况下从列表my_foods中提取一个切片,从而创建了这个列表的副本,再将该副本存储到变量friend_foods中。打印每个列表后,我们发现它们包含的食品相同:

    My favorite foods are:
    ['pizza', 'falafel', 'carrot cake']
    My friend's favorite foods are: 
    ['pizza', 'falafel', 'carrot cake']
    

    为了核实我们确实有两个列表,下面在每个列表中都添加一种食品,并核实每个列表都记录了相应人员喜欢的食品:

    my_foods = ['pizza', 'falafel', 'carrot cake'] 5
    friend_foods = my_foods[:]
    my_foods.append('cannoli')
    friend_foods.append('ice cream') 
    print("My favorite foods are:")
    print(my_foods)
    print("\nMy friend's favorite foods are:") 
    print(friend_foods)
    

    与前一个示例一样,我们首先将my_foods的元素复制到新列表friend_foods中。接下来,在每个列表中都添加一种食品:在列表my_foods中添加cannoli,而在friend_foods中添加ice cream。最后,打印这两个列表,核实这两种食品包含在正确的列表中。

    My favorite foods are:
    ['pizza', 'falafel', 'carrot cake', 'cannoli']
    My friend's favorite foods are:
    ['pizza', 'falafel', 'carrot cake', 'ice cream']
    

    上面的输出表明,cannoli包含在你喜欢的食品列表中,而ice cream没有。ice cream包含在你朋友喜欢的食品列表中,而cannoli没有。倘若我们只是简单地将my_foods赋给friend_foods,就不能得到两个列表。例如,下例演示了在不使用切片的情况下复制列表的情况:

    my_foods = ['pizza', 'falafel', 'carrot cake']
    #这行不通 
    friend_foods = my_foods
    my_foods.append('cannoli') 
    friend_foods.append('ice cream')
    print("My favorite foods are:") 
    print(my_foods)
    print("\nMy friend's favorite foods are:") 
    print(friend_foods)
    

    这里将my_foods赋给friend_foods,而不是将my_foods的副本存储到friend_foods。这种语法实际上是让Python将新变量friend_foods关联到包含在my_foods中的列表,因此这两个变量都指向同一个列表。鉴于此,当我们将cannoli添加到my_foods中时,它也将出现在friend_food中;同样,虽然ice cream好像只被加入到了friend_foods中,但它也将出现在这两个列表中。
    输出表明,两个列表是相同的,这并非我们想要的结果:

    My favorite foods are:
    ['pizza', 'falafel', 'carrot cake', 'cannoli', 'ice cream']
    My friend's favorite foods are:
    ['pizza', 'falafel', 'carrot cake', 'cannoli', 'ice cream']
    

    8-1 动物:想出至少三种有共同特征的动物,将这些动物的名称存储在一个列表中,再使用for循环将每种动物的名称都打印出来。
    修改这个程序,使其针对每种动物都打印一个句子,如"A dog would make a great pet"。在程序末尾添加一行代码,指出这些动物的共同之处,如打印诸如"Any of these animals would make a great pet!"这样的句子。
    8-2 数到 20:使用一个 for 循环打印数字 1~20(含)。
    8-3 计算 1~ 1000000 的总和:创建一个列表,其中包含数字1~1000000,再使用min()和max()核实该列表确实是从1开始,到1000000 结束的。另外,对这个列表调用函数sum(),体会一下Python将一百万个数字相加需要多长时间。
    8-4 3的倍数:创建一个列表,其中包含 3~30 内能被3整除的数字;再使用一个for循环将这个列表中的数字都打印出来。
    8-5 切片:修改8-1的代码,在末尾添加几行代码,以完成如下任务。 打印消息"The first three items in the list are:",再使用切片来打印列表的前三个元素。打印消息"Three items from the middle of the list are:",再使用切片来打印列表中间的三个元素。打印消息"The last three items in the list are:",再使用切片来打印列表末尾的三个元素。

    想查看作业答案可以去我的Githu仓库


    相关文章

      网友评论

        本文标题:【Python 1-8】Python手把手教程之——管理列表Li

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