第一章 Python基础
一、数据类型和变量
Python的数据类型包括整数、浮点数、字符串、布尔值、空值、变量、常量等。其中整数可以表示任意大小的整数;空值是Python里一个特殊的值,用None表示。
对于变量:Python中采用动态语言的方式,即变量本身类型并不固定,如下:
a=100 #这里a是一个整数类型
a="abc" #这里a又变成了字符串类型
变量的另外一个重点需要理解的是内存中的表示,当有以下代码:
a="ABC"
解释器做了两个事情:(1)在内存中创建了一个”ABC”的字符串;(2)在内存中创建了一个名为a的变量,并将其指向上述”ABC”。
当代码如下:
a="ABC"
b=a
a="XYZ"
print(b)
这里关键是理解第二句b=a的实际意义是将a的指向赋值给b,而此时a的指向为第一行”ABC”的内存,所以b也指向”ABC”,而第三句后又创建了一段存储字符串”XYZ”的内存,并使a指向该段内存,但b指向未变,所以第四行输出结果为ABC。
对于常量:Python中通常用全部大写的变量标明为常量,如:
PI=3.14159265359
实际上PI仍为一个变量,Python并不提供任何机制保证PI不被改变,所以这里用大写变量名只是一个习惯用法,而PI的值实质上仍然是可以改变的。
二、字符串和编码
1、字符编码
在最初的字符编码中,使重点内容用的是美国的ASCII码,只有一个字节长度。但对于中文、日文等等,一个字节是不够的。Unicode编码把所有语言都统一到一套编码中,通常使用两个字节。
但对于英文字母来说,用ASCII码比Unicode节约了一半的存储空间,所有又出现了把Unicode编码转化为可变长编码的UTF-8编码,英文字母为1字节,中文通常为3字节,只有很生僻的字符才为4-6字节。
目前计算机系统通用的字符编码工作方式总结如下:在计算机内存中统一使用Unicode编码,当需要保存到磁盘或需要传输的时候,就转换为UTF-8编码。如用记事本编辑时,先从文件读取的UTF-8字符转换为Unicode字符到内存里,编辑完后保存再把Unicode转换为UTF-8保存到文件。
2、格式化
>>> "Hello,%s" % "world"
'Hello,world'
>>> "Hi,%s,you have $%d." %("Michael",100000)
'Hi,Michael,you have $100000.'
上述代码中%运算符就是用来格式化字符串的。在字符串内部,%s表示用字符串替换,%d表示用整数替换;字符串中有几个%运算符,后面就跟几个变量或值,同时对应好顺序。
其他占位符包括:%f表示浮点数,%x表示十六进制整数。
另外,格式化整数和浮点数还可以指定是否补0和整数与小数的位数,如%2d表示用两位显式一个整数(如个位数则十位为空格),如%02d表示对于空位用0补充:
>>> '%2d-%02d' %(3,1)
' 3-01'
>>> '%.2f' % 3.1415926
'3.14'
小练习:小明成绩从去年72分提升到今年85分,请计算小明成绩提升的百分比,并用字符串格式化显式出,保留小数点后1位。
lastyearScore=72
thisyearScore=85
improve=(thisyearScore/lastyearScore-1)*100
print("小明今年的成绩比去年提高了%.1f%%" % improve)
三、使用list和tuple
1、list列表
list是Python内置的一种数据类型,它是一种有序的集合,并且可以增加或删除其中元素,如可以用list表示一个班级里所有同学的名字:
>>> classmates=['Machasl','Bob','Tracy']
>>> classmates
['Machasl', 'Bob', 'Tracy']
可以通过len()函数获取list中元素的数量,并通过索引访问各个元素,索引从0开始。也可以从尾部开始,此时索引按-1、-2…这样的顺序。
如果要增加元素,可在尾部增加;如果要删除尾部的元素,可以用pop()方法;如果要删除指定位置的元素,可以用pop(i)方法,其中i是索引位置:
>>> classmates.append('Tom')
>>> classmates
['Machasl', 'Bob', 'Tracy', 'Tom']
>>> classmates.append('Nick')
>>> classmates
['Machasl', 'Bob', 'Tracy', 'Tom', 'Nick']
>>> classmates.pop()
'Nick'
>>> classmates.pop(-2)
'Tracy'
>>> classmates
['Machasl', 'Bob', 'Tom']
如果要修改元素内容,可以直接赋值:
>>> classmates[0]='Mary'
>>> classmates
['Mary', 'Bob', 'Tom']
对于list中的元素,各个元素的数据类型可以是不相同的,甚至也可以是另一个list:
>>> list1=[10,'apple',True]
>>> list1
[10, 'apple', True]
>>> list2=['abc',False,list1]
>>> list2
['abc', False, [10, 'apple', True]]
对于上述后一种情况实则类似于二维数组了,对于list1中的第2个元素,可以如下访问:
>>> list1[1]
'apple'
>>> list2[2][1]
'apple'
2、tuple元组
Python中另外一种有序列表称为元组。但tuple一旦初始化就不能修改:
>>> classmates=('Tom','Harry')
>>> classmates
('Tom', 'Harry')
tuple因为不可变性,所以不像list一样有append()、pop()这样的方法,在避免元素会被修改时候往往可以使用tuple。需要注意如果定义一个只有一个元素的元组,需要如下定义,以避免解释器误解为定义的是整数1:
>>> t1=(1,)
>>> t1
(1,)
tuple的不可变性指的是其元素所指向的不可变,如下代码:
>>> t=('a','b',['A','B'])
>>> t[2][0]='C'
>>> t[2][1]='D'
>>> t
('a', 'b', ['C', 'D'])
这里t的第三个元素指向的为一个列表,第三个元素指向并没有变化,变化的是该列表的内容。
小练习:小明身高1米75,体重80.5公斤。请计算他的BMI指数。
height=1.75
weight=80.5
h=height**2
bmi=weight/h
print('小明的BMI指数为%.2f' % bmi)
if bmi<18.5:
print('过轻')
elif 18.5<=bmi<=25:
print('正常')
elif 25<=bmi<=28:
print('过重')
elif 28<=bmi<=32:
print('肥胖')
else:
print('严重肥胖')
四、使用dict和set
1、dict字典
dict采用键-值(key-value)存储,具有极快的查找速度。
>>> d={'Michael':95,'Bob':75,'Tracy':85}
>>> d['Michael']
95
dict查找极快的原因在于对应一个key值,dict可以先计算出其值所处的位置,不会因为dict元素的增多而变慢。而这种计算位置的算法称为哈希算法(Hash),因为如此,键必须是唯一的,同时键对应的值也是唯一的。
可以通过in判断key在dict中是否存在,也可以通过get方法,如果不存在则返回None或者指定的值:
>>> 'Thomas' in d
False
>>> d.get('Thomas')
>>> d.get('Thomas',-1)
-1
如果要删除一个key,则用pop(key)方法,对应的value也会被删除:
>>> d.pop('Bob')
75
>>> d
{'Tracy': 85, 'Michael': 95}
需要牢记住dict的键必须是不可变对象,如字符串、整数等。如果键可变,则会影响先前的哈希计算。
2、set
set类似于dict,也是一组key的集合,但并不存储value。由于key不能重复,所以在set中没有重复的key。
要创建一个set,需要提供一个list作为输入集合:
>>> s=set([1,2,3])
>>> s
{1, 2, 3}
>>> s=set([1,2,3,2,1])
>>> s
{1, 2, 3}
通过add(key)方法可以给set中添加元素,添加已有的元素是合法但无效的:
>>> s.add(3)
>>> s
{1, 2, 3}
>>> s.add(8)
>>> s
{8, 1, 2, 3}
通过remove(key)可以删除元素:
>>> s.remove(2)
>>> s
{8, 1, 3}
set可以看作数学意义上的无序并且无重复元素的集合,因此两个set可以进行数学意义上的交集、并集等操作:
>>> s1=set([1,3,5,7,9,12])
>>> s2=set([1,2,3,5,6,9,11])
>>> s1&s2
{1, 3, 5, 9}
>>> s1|s2
{1, 2, 3, 5, 6, 7, 9, 11, 12}
set和dict的唯一区别仅在于没有存储value,因此set存储同样不可放入可变对象。
3、不可变对象
str字符串是不可变对象,而list是可变对象。
对于可变对象,比如list,对其进行操作,list内部的内容是会变化的,比如:
>>> a=['c','b','a']
>>> a.sort()
>>> a
['a', 'b', 'c']
而对于不可变对象,比如str,对str进行操作:
>>> a='abc'
>>> a.replace('a','A')
'Abc'
>>> a
'abc'
虽然字符串提供了replace()方法,但实质上是新创建了一个字符串并返回给方法,对于上述代码,a是一个变量,其指向为’abc’所处内存空间,在replace()时,新建了一段内存空间。
对于不可变对象来说,调用对象自身的任意方法,也不会改变对象自身的内容,而是这些方法会创建新的对象并返回。