乐趣区

关于python3:Python-18Python手把手教程之管理列表List

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

在上一节咱们学习了如何创立一个列表,在列表外面插入、删除数据等操作。
本节咱们学习如何治理列表。

遍历列表

在日常开发中,咱们常常须要遍历列表的所有元素,对每个元素执行雷同的操作。例如,在治理商场的蔬菜时候,须要给所有的蔬菜商品都打 7 折,并从新生成价格。当咱们须要对列表中的每个元素都执行雷同的操作时,可应用 Python 中的 for 循环。
<!–more–>
假如咱们有一个蔬菜名单,须要将其中每种蔬菜的名字都打印进去。为此,咱们能够采纳元素下标的形式别离获取名单中的每个名字,但这种做法会导致多个问题。例如,如果名单很长,将蕴含大量反复的代码。另外,每当名单的长度发生变化时,都必须批改代码。通过应用 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 仓库


退出移动版