Python基础入门
Python学习
第一个Python程序
1 | >>> 100+200 |
如果要让Python打印出指定的文字,可以用print()函数,然后把希望打印的文字用单引号或者双引号括起来,但不能混用单引号和双引号:
第一个hello world!
1 | >>> print('hello, world') |
这种用单引号或者双引号括起来的文本在程序中叫字符串,今后我们还会经常遇到。
最后,用exit()退出Python,我们的第一个Python程序完成!唯一的缺憾是没有保存下来,下次运行时还要再输入一遍代码。
输入和输出
用print()在括号中加上字符串,就可以向屏幕上输出指定的文字。比如输出’hello, world’,用代码实现如下:
1 | >>> print('hello, world') |
输出
print()函数也可以接受多个字符串,用逗号“,”隔开,就可以连成一串输出:
1 | >>> print('The quick brown fox', 'jumps over', 'the lazy dog') |
print()也可以打印整数,或者计算结果:
1 | >>> print(300) |
因此,我们可以把计算100 + 200的结果打印得更漂亮一点:
1 | >>> print('100 + 200 =', 100 + 200) |
输入
现在,你已经可以用print()输出你想要的结果了。但是,如果要让用户从电脑输入一些字符怎么办?Python提供了一个input(),可以让用户输入字符串,并存放到一个变量里。比如输入用户的名字:
1 | >>> name = input() |
数据类型和变量
数据类型
整数 浮点数 字符串
字符串:’I'm "OK"!’表示的字符串内容是:I’m “OK”!
布尔值
布尔值和布尔代数的表示完全一致,一个布尔值只有True、False两种值,要么是True,要么是False,在Python中,可以直接用True、False表示布尔值(请注意大小写),也可以通过布尔运算计算出来:
1 | >>> True |
布尔值可以用and、or和not运算
1 | >>> True and True |
not运算是非运算,它是一个单目运算符,把True变成False,False变成True:
1 | >>> not True |
布尔值经常用在条件判断中,比如:
1 | if age >= 18: |
常量
所谓常量就是不能变的变量,比如常用的数学常数π就是一个常量。在Python中,通常用全部大写的变量名表示常量:
PI = 3.14159265359
最后解释一下整数的除法为什么也是精确的。在Python中,有两种除法,一种除法是/:
1 | >>> 10 / 3 |
除法计算结果是浮点数,即使是两个整数恰好整除,结果也是浮点数:
1 | >>> 9 / 3 |
还有一种除法是//,称为地板除,两个整数的除法仍然是整数:
1 | >>> 10 // 3 |
Python的字符串
1 | >>> print('包含中文的str') |
对于单个字符的编码,Python提供了ord()函数获取字符的整数表示,chr()函数把编码转换为对应的字符:
1 | >>> ord('A') |
要计算str包含多少个字符,可以用len()函数:
1 | >>> len('ABC') |
len()函数计算的是str的字符数,如果换成bytes,len()函数就计算字节数:
1 | >>> len(b'ABC') |
格式化
在Python中,采用的格式化方式和C语言是一致的,用%实现,举例如下:
1 | >>> 'Hello, %s' % 'world' |
如果你不太确定应该用什么,%s永远起作用,它会把任何数据类型转换为字符串:
1 | >>> 'Age: %s. Gender: %s' % (25, True) |
有些时候,字符串里面的%是一个普通字符怎么办?这个时候就需要转义,用%%来表示一个%:
1 | >>> 'growth rate: %d %%' % 7 |
使用list和tuple
list
Python内置的一种数据类型是列表:list。list是一种有序的集合,可以随时添加和删除其中的元素。
比如,列出班里所有同学的名字,就可以用一个list表示:
1 | >>> classmates = ['Michael', 'Bob', 'Tracy'] |
变量classmates就是一个list。用len()函数可以获得list元素的个数:
1 | >>> len(classmates) |
用索引来访问list中每一个位置的元素,记得索引是从0开始的:
1 | >>> classmates[0] |
以此类推,可以获取倒数第2个、倒数第3个:
1 | >>> classmates[-2] |
要删除list末尾的元素,用pop()方法:
1 | >>> classmates.pop() |
也可以把元素插入到指定的位置,比如索引号为1的位置:
1 | >>> classmates.insert(1, 'Jack') |
list元素也可以是另一个list,比如:
1 | >>> s = ['python', 'java', ['asp', 'php'], 'scheme'] |
tuple
另一种有序列表叫元组:tuple。tuple和list非常类似,但是tuple一旦初始化就不能修改,比如同样是列出同学的名字:
1 | >>> classmates = ('Michael', 'Bob', 'Tracy') |
现在,classmates这个tuple不能变了,它也没有append(),insert()这样的方法。其他获取元素的方法和list是一样的,你可以正常地使用classmates[0],classmates[-1],但不能赋值成另外的元素。
1 | >>> t = (1, 2) |
如果要定义一个空的tuple,可以写成():
1 | >>> t = () |
但是,要定义一个只有1个元素的tuple,如果你这么定义:
1 | >>> t = (1) |
定义的不是tuple,是1这个数!这是因为括号()既可以表示tuple,又可以表示数学公式中的小括号,这就产生了歧义,因此,Python规定,这种情况下,按小括号进行计算,计算结果自然是1。
1 | >>> t = (1,) |
Python在显示只有1个元素的tuple时,也会加一个逗号,,以免你误解成数学计算意义上的括号。
最后来看一个“可变的”tuple:
1 | >>> t = ('a', 'b', ['A', 'B']) |
条件判断
1 | age = 20 |
当然上面的判断是很粗略的,完全可以用elif做更细致的判断:
1 | age = 3 |
循环
Python的循环有两种,一种是for…in循环,依次把list或tuple中的每个元素迭代出来,看例子:
1 | names = ['Michael', 'Bob', 'Tracy'] |
再比如我们想计算1-10的整数之和,可以用一个sum变量做累加:
1 | sum = 0 |
如果要计算1-100的整数之和,从1写到100有点困难,幸好Python提供一个range()函数,可以生成一个整数序列,再通过list()函数可以转换为list。比如range(5)生成的序列是从0开始小于5的整数:
1 | sum = 0 |
使用dict和set
Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。
举个例子,假设要根据同学的名字查找对应的成绩,如果用list实现,需要两个list:
1 | names = ['Michael', 'Bob', 'Tracy'] |
把数据放入dict的方法,除了初始化时指定外,还可以通过key放入:
1 | >>> d['Adam'] = 67 |
由于一个key只能对应一个value,所以,多次对一个key放入value,后面的值会把前面的值冲掉:
1 | >>> d['Jack'] = 90 |
要避免key不存在的错误,有两种办法,一是通过in判断key是否存在:
1 | >>> 'Thomas' in d |
要删除一个key,用pop(key)方法,对应的value也会从dict中删除:
1 | >>> d.pop('Bob') |
和list比较,dict有以下几个特点:
1.查找和插入的速度极快,不会随着key的增加而增加;
2.需要占用大量的内存,内存浪费多。
而list相反:
1.查找和插入的时间随着元素的增加而增加;
2.占用空间小,浪费内存很少。
set
set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。
要创建一个set,需要提供一个list作为输入集合:
1 | >>> s = set([1, 2, 3]) |
注意,传入的参数[1, 2, 3]是一个list,而显示的{1, 2, 3}只是告诉你这个set内部有1,2,3这3个元素,显示的顺序也不表示set是有序的。。
重复元素在set中自动被过滤:
1 | >>> s = set([1, 1, 2, 2, 3, 3]) |
通过add(key)方法可以添加元素到set中,可以重复添加,但不会有效果:
1 | >>> s.add(4) |
通过remove(key)方法可以删除元素:
1 | >>> s.remove(4) |
set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集、并集等操作:
1 | >>> s1 = set([1, 2, 3]) |
不可变对象
对于可变对象,比如list,对list进行操作,list内部的内容是会变化的,比如:
1 | >>> a = ['c', 'b', 'a'] |
而对于不可变对象,比如str,对str进行操作:
1 | >>> a = 'abc' |
函数
调用函数
调用abs函数:
1 | >>> abs(100) |
而max函数max()可以接收任意多个参数,并返回最大的那个:
1 | >>> max(1, 2) |
数据类型转换
Python内置的常用函数还包括数据类型转换函数,比如int()函数可以把其他数据类型转换为整数:
1 | >>> int('123') |
函数名其实就是指向一个函数对象的引用,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”:
1 | >>> a = abs # 变量a指向abs函数 |
定义函数
我们以自定义一个求绝对值的my_abs函数为例:
1 | def my_abs(x): |
返回多个值
比如在游戏中经常需要从一个点移动到另一个点,给出坐标、位移和角度,就可以计算出新的新的坐标:
1 | import math |
然后,我们就可以同时获得返回值:
1 | >>> x, y = move(100, 100, 60, math.pi / 6) |
函数的参数
位置参数
我们先写一个计算x*x的函数:
1 | def power(x): |
当我们调用power函数时,必须传入有且仅有的一个参数x:
1 | >>> power(5) |
现在,如果我们要计算x3怎么办?可以再定义一个power3函数,但是如果要计算x4、x5……怎么办?我们不可能定义无限多个函数。
你也许想到了,可以把power(x)修改为power(x, n),用来计算xn,说干就干:
1 | def power(x, n): |
对于这个修改后的power(x, n)函数,可以计算任意n次方:
1 | >>> power(5, 2) |
递归函数
举个例子,我们来计算阶乘n! = 1 x 2 x 3 x … x n,用函数fact(n)表示,可以看出:
fact(n) = n! = 1 x 2 x 3 x … x (n-1) x n = (n-1)! x n = fact(n-1) x n
于是,fact(n)用递归的方式写出来就是:
1 | def fact(n): |
上面就是一个递归函数。可以试试:
1 | >>> fact(1) |
上面的fact(n)函数由于return n * fact(n - 1)引入了乘法表达式,所以就不是尾递归了。要改成尾递归方式,需要多一点代码,主要是要把每一步的乘积传入到递归函数中:
1 | def fact(n): |
尾递归调用时,如果做了优化,栈不会增长,因此,无论多少次调用也不会导致栈溢出。