本章内容来自书籍,记录下来仅方便复习,如有侵权,请联系作者删除。
一、遍历整个列表
遍历列表中的所有元素,并对每个元素执行相同的操作。可用Python中的for循环。
names = ['tom','john','mary','jenny']
for name in names:
print(name)
运行结果:
tom
john
mary
jenny
让Python从列表names中取出每一个名字,将其存储在遍历name中,并打印出来。
1. 深入地研究循环
循环是让计算机自动完成重复工具的常见方式之一,列表中的每个元素,都将执行循环体中的指定步骤
- 这一步让Python读取列表names中的值,是控制循环次数的行 ,从第一个元素开始取值,每取值一次就进行一次循环,直到最后一个元素,
for name in names:
name = name[0] 第一次循环
-->name = name[1] 第二次循环
-->name = name[2] 第三次循环
-->...
-->name = name[-1] 最后一次循环
- 这一步是循环体中的打印元素命令,每循环一次,都打印一次name元素
print(name)
- 存储列表中的每个字的临时变量,可用指定任何名称,如:
for cat in cats:
for dog in dags:
for item in items:
2. 在for循环中执行跟多的操作
打印元素,打印字符串,添加制表符,换行符等
names = ['tom','john','mary','jenny']
for name in names:
print("I will say hello to "+name+" now")
print("\t\'Hello:\t"+name+".\'\n")
print("I have already greeted everyone.")
运行结果:
I will say hello to tom now
'Hello: tom.'
I will say hello to john now
'Hello: john.'
I will say hello to mary now
'Hello: mary.'
I will say hello to jenny now
'Hello: jenny.'
I have already greeted everyone.
二、避免缩进错误
Python根据缩进来判断代码行与前一个代码行的关系。for循环中,循环体中所有的操作都需要缩进,没有缩进的代码表示不在该循环体内。
1. 忘记缩进,提示缩进错误
names = ['tom','john','mary','jenny']
for name in names:
print("I will say hello to "+name+" now")
print("\t\'Hello:\t"+name+".\'\n")
print("I have already greeted everyone.")
运行结果:
IndentationError: expected an indented block
2. 非语法上的缩进问题,为逻辑错误,不提示错误
- 忘记缩进额外的代码行,不提示错误
如下所示,忘记缩进第二个输出语句,所以该输出语句不在循环体中,Python代码是合法的,可以运行程序,但运行结果不是预期的,这是逻辑错误。
names = ['tom','john','mary']
for name in names:
print("I will say hello to "+name+" now")
print("\t\'Hello:\t"+name+".\'\n")
print("I have already greeted everyone.")
运行结果
I will say hello to tom now
I will say hello to john now
I will say hello to mary now
'Hello: mary.'
I have already greeted everyone.
- 缩进多余的代码行,为逻辑错误,不提示错误
如下所示,第三个输出语句不应该缩进,但此时缩进了,表示该语句在循环体中,Python代码是合法的,可以运行程序。
names = ['tom','john','mary']
for name in names:
print("I will say hello to "+name+" now")
print("\t\'Hello:\t"+name+".\'\n")
print("I have already greeted everyone.")
运行结果:
I will say hello to tom now
'Hello: tom.'
I have already greeted everyone.
I will say hello to john now
'Hello: john.'
I have already greeted everyone.
I will say hello to mary now
'Hello: mary.'
I have already greeted everyone.
3. 不必要的缩进,提示缩进错误
message = "hello python"
print(message)
运行结果:
IndentationError: unexpected indent
4. 遗漏冒号,提示语法错误
for语句末尾的冒号告诉Python,下一行是循环的第一行
names = ['tom','john','mary']
for name in names
print("I will say hello to "+name+" now")
print("\t\'Hello:\t"+name+".\'\n")
print("I have already greeted everyone.")
运行结果:
SyntaxError: invalid syntax
三、 创建数字列表
数据可视化中,处理的几乎都是有数字组成的几乎,如温度,距离,人口数量,经度,维度。列表非常适用于存储数字集合,Python提供了很多工具,可以高效处理数字列表。
1. 使用函数range()
Python函数range(),可以生成一系列数字
for value in range(1,5):
print(value)
运行结果:
1
2
3
4
range(start: int, stop: int, step: int=...)
函数range()让Python从你指定的第一个值开始数,并在达到你指定的第二个值后停止,因此输出不包含第二个值。
第三个值表示指定的步长。
2. 使用函数range()创建数字列表
要创建数字列表,可使用函数list()将range()的结果直接转换为列表。
- 简单数字列表
numbers = list(range(1,6))
print(numbers)
运行结果:
[1, 2, 3, 4, 5]
- 指定步长
数字列表从2开始,不断加2,直到达到或超过终值11
numbers = list(range(2,11,2))
print(numbers)
运行结果:
[2, 4, 6, 8, 10]
- 创建平方数
使用函数range()几乎可以创建任何需要的数字集,如创建乘方数字集,两个星号(**
)表示乘方运算
numbers = []
for number in range(1,11):
numbers.append(number**2)
print(numbers)
运行结果:
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
3. 对数字列表执行简单的统计计算
有几个专门处理数字列表的Python函数,如最大值max()
,最小值min()
,求和sum()
numbers = list(range(1,11))
print(max(numbers))
print(min(numbers))
print(sum(numbers))
运行结果:
10
1
55
4. 列表解析
列表解析将for循环和创建新元素的代码合并成一行,并自动附加新元素。
squares = [value**2 for value in range(1,11)]
print(squares)
运行结果:
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
首先指定一个空列表,squares = []
然后在中括号中添加表达式,用于生成你要存储的列表中的值,value**2
接下来编写一个for循环,用于给表达式提供值,for value in range(1,11)
四、使用列表的一部分
接下来,学习处理列表的部分元素——Python称之为切片
1. 切片
要创造切片,可指定要使用的第一个元素和最后一个元素的索引,与函数range()一样,Python在达到你指定的第二个索引前面的元素后停止。返回切片的值
name[起始索引:终止索引]
- 起始索引
自然数,表示切片从该自然数开始,正序提取元素
负数,表示切片从该负数开始,正序提取元素
没有指定,Python将自动从列表头开始提取元素
alphabet = ['a','b','c','d','e','g','h','i','j','k']
print(alphabet[3:5])
print(alphabet[-3:-1])
print(alphabet[:3])
运行结果:
['d', 'e']
['i', 'j']
['a', 'b', 'c']
- 终止索引
自然数,表示切片在该自然数结束,正序提取元素
负数,表示切片在该负数结束,正序提取元素
没有指定,Python将默认让切片终止于列表末尾
alphabet = ['a','b','c','d','e','g','h','i','j','k']
print(alphabet[3:5])
print(alphabet[3:-2])
print(alphabet[3:])
运行结果:
['d', 'e']
['d', 'e', 'g', 'h', 'i']
['d', 'e', 'g', 'h', 'i', 'j', 'k']
PS: 终止索引的值,可以大于列表的长度。此时切片将终止于列表末尾
alphabet = ['a','b','c','d','e','g','h','i','j','k']
print(alphabet[7:30])
运行结果:
['i', 'j', 'k']
2. 遍历切片
如果要遍历列表的部分元素,可在for循环中使用切片
alphabet = ['a','b','c','d','e','g','h','i','j','k']
for i in alphabet[:3]:
print(i)
运行结果:
a
b
c
3. 复制列表
复制列表,创建一个包含整个列表的切片。这里主要是讲浅拷贝
- 复制时创建副本,如同时省略起始索引和终止索引(
[:]
)
使用切片拷贝,创建原列表的表层副本,并保存在新的变量中。二者指向两个列表。
import copy
son = ['python', 'copy']
base = ['a', 'b', 'c', 'd', 'e', son]
bak1 = base[:]
#列表表层的值改变,副本的值不会跟着改变
base[0] = 'test'
print('-' * 15, '[:]拷贝,修改列表浅层的值', '-' * 15)
print('base: ', base)
print("bak1: ", bak1)
print("\n")
#列表深层的值改变,副本的值跟着改变
son[0] = 'java'
print('-' * 15, '[:]拷贝,修改列表深层的值', '-' * 15)
print('base: ', base)
print("bak1: ", bak1)
运行结果:
--------------- [:]拷贝,修改列表浅层的值 ---------------
base: ['test', 'b', 'c', 'd', 'e', ['python', 'copy']]
bak1: ['a', 'b', 'c', 'd', 'e', ['python', 'copy']]
--------------- [:]拷贝,修改列表深层的值 ---------------
base: ['test', 'b', 'c', 'd', 'e', ['java', 'copy']]
bak1: ['a', 'b', 'c', 'd', 'e', ['java', 'copy']]
创建副本的拷贝方式有四种:
(1)切片: bak1 = base[:]
(2)list工厂函数:bak2 = list(base)
(3)python list对象的copy方法:bak3 = base.copy()
(4)copy模块的copy方法:bak4 = copy.copy(base)
- 复制时创建关联,如使用等于号(
=
)
使用等于号拷贝,没有创建列表的表层副本。让Python将新变量关联到原列表上,二者指向同一个列表。
import copy
son = ['python', 'copy']
base = ['a', 'b', 'c', 'd', 'e', son]
bak1 = base
#列表表层的值改变,bak1也跟着改变
base[0] = 'test'
print('-' * 20, '“=”浅拷贝', '-' * 20)
print('base: ', base)
print("bak1: ", bak1)
运行结果:
base: ['test', 'b', 'c', 'd', 'e', ['python', 'copy']]
bak1: ['test', 'b', 'c', 'd', 'e', ['python', 'copy']]
五、深拷贝和浅拷贝
Python中对于对象的拷贝分为浅拷贝和深拷贝(函数:copy.deepcopy()
)两种方式。
1. Python数据类型分为值类型和引用类型
基本数据类型/值类型:对象本身不允许修改,数值的修改实际上是让变量指向一个新的对象(包含字符串、元组、数值)
引用数据类型/引用类型:对象本身允许修改(包含列表、字典)
(1)基本数据类型
基本数据类型保存在栈内存中,形式如下:栈内存中分别存储变量的标识符以及变量的值。
字符串a = "A"
在栈内存中时这样的:
(2)引用数据类型
引用数据类型保存在堆内存中,栈内存存储的变量的标识符以及对象在堆内存中的存储地址,当需要访问引用数据类型的值是,首先从栈中获得该对象的地址指针,然后再从对应的堆内存中获取所需的数据。
字典a = {name:"jack"}
在内存中是这样的:
2. 基本数据类型和引用数据类型的拷贝
浅拷贝:仅仅是复制了引用(地址),换句话说,复制了之后,原来的变量和新的变量指向同一个东西,彼此之间的操作会互相影响。
深拷贝:复制实例,在堆中重新分配内存,拥有不同的地址,但值是一样的,复制之后的对象与原来的对象完全隔离,互不影响。
深浅拷贝的主要区别就是:复制的是引用(地址)还是复制的是实例。
基本数据类型的浅拷贝和深拷贝效果一样?
(3)基本数据类型的浅拷贝
这里的浅拷贝使用 “=
” 号
a = 1
b = a
a = 2
print("a = "+str(a))
print("b = "+str(b))
运行结果:
a = 2
b = 1
改变 a 变量的值,并不会影响 b 的值。
内存中是这样的:
a = 1
b = a
a = 2
(4)引用数据类型的浅拷贝:当你在复制引用类型的时候,实际上只是复制了指向堆内存的地址,即原来的变量与复制的新变量指向了同一个东西。
这里的浅拷贝使用 “=
” 号
a = {"name":"jack","age":20}
b = a
a["age"] = 23
print("a = " + str(a))
print("b = " + str(b))
运行结果:
a = {'name': 'jack', 'age': 23}
b = {'name': 'jack', 'age': 23}
改变 a 变量的值,会影响 b 的值。
内存中是这样的:
a = {"name":"jack","age":20}
b = a
a["age"] = 23
(5)引用数据类型的深拷贝
Python的深拷贝使用copy.deepcopy()
import copy
a = {"name":"jack","age":20}
b = copy.deepcopy(a)
a["age"] = 23
print("a = " + str(a))
print("b = " + str(b))
运行结果:
a = {'name': 'jack', 'age': 23}
b = {'name': 'jack', 'age': 20}
让b在内存中像下图这样,就是深拷贝。
实现过程:利用 递归 来实现深复制,对属性中所有引用类型的值,遍历到是基本类型的值为止。
六、元组
Python将不能修改的值称为不可变的,而不可变的列表被称为元组。
1. 定义元组
元组看起来犹如列表,但使用圆括号而不是方括号来标识。定义元组后,就可以使用索引来访问其元素,就像访问列表元素一样。
元组中的元素不能修改,如果试图修改则会报错
alphabets = ('a','b','c','d','e')
alphabets[2] = 'test'
运行结果:
TypeError: 'tuple' object does not support item assignment
2. 遍历元组中的所有值
像列表一样,使用用for循环遍历
alphabets = ('a','b','c','d','e')
for alphabet in alphabets:
print(alphabet)
运行结果:
a
b
c
d
e
- 修改元组变量
虽然不能修改元组的元素,但是可以给存储元组的变量赋值
alphabets = ('a','b','c','d','e')
print(alphabets)
alphabets = ('test1','test2','c','d','e')
print(alphabets)
运行结果:
('a', 'b', 'c', 'd', 'e')
('test1', 'test2', 'c', 'd', 'e')
相比于列表,元组是更简单的数据结果。如果需要存储的一组值在程序中的整个生命周期内都不可变,可使用元组。
七、设置代码格式
- 格式设置指南
PEP8是最古老的PEP之一,它向Python程序员提供了代码格式设置指南 - 缩进
PEP8建议每级缩进都使用四个空格,既可以提高可读性,又留下了足够的多级缩进空间。一般不用制表符缩进,因为不同软件制表符的长度不一样。 - 行长
很多Python程序员都建议每行不超过80个字符,PEP8还建议注释的行长都不超过72个字符。
PEP8中有关行长的指南,有一条可逾越的红线,这是一个视觉标志,让你知道不能越过的界限在什么地方。 - 空行
要将程序的不同部分分开,可使用空行。不建议滥用,影响可读性。
还有其他格式的指南,以后再学习。
八、小结、补充
今天学习了如何高效处理列表中的元素,使用for循环遍历列表,Python如何根据缩进来确定程序的结构以及如何避免一些常见的缩进错误,创建简单的数字列表,复制列表,元组,代码格式。
缩进错误:IndentationError: unexpected indent
数值:
int(符号整数):通常被称为是整数或整数,没有小数点的正或负整数。
long(长整数):无限大小的整数,这样写整数和一个大写或小写的L。
float(浮点实际值):小数除以整数部分和小数部分的书面。
complex (复数):a+bi, a是真正的数字部分,b是虚部。复数不使用Python编程。
深拷贝,浅拷贝
https://www.cnblogs.com/echolun/p/7889848.html
https://zhuanlan.zhihu.com/p/26282765