一、 输入与输出
输出
>>> print('The quick brownfox', 'jumps over', 'the lazy dog')
The quick brown fox jumps over the lazy dog
print()
会依次打印每个字符串,遇到逗号“,”会输出一个空格
输入
>>> name = input()
Michael
1、#为注释
2、‘’和 “” 都是字符串
3、当语句以冒号:结尾时,缩进的语句视为代码块
4、大小写敏感
5、这种变量本身类型不固定的语言称之为动态语言,与之对应的是静态语言。
6、 // 是 整除
7、在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。
用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件
浏览网页的时候,服务器会把动态生成的Unicode内容转换为UTF-8再传输到浏览器
在最新的Python 3版本中,字符串是以Unicode编码的
8、Python提供了ord()函数获取字符的整数表示,chr()函数把编码转换为对应的字符
9、bytes
类型的数据用带b
前缀的单引号或双引号表示
要在网络上传输,或者保存到磁盘上,就需要把str
变为以字节为单位的bytes
以Unicode表示的str
通过encode()
方法可以编码为指定的bytes
>>> 'ABC'.encode('ascii')
b'ABC'
>>> '中文'.encode('utf-8')
b'\xe4\xb8\xad\xe6\x96\x87'
>>> '中文'.encode('ascii')
Traceback (most recent call last):
File "
<stdin>", line 1, in
<module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
如果我们从网络或磁盘上读取了字节流,那么读到的数据就是bytes
。要把bytes
变为str
,就需要用decode()
方法
要计算str包含多少个字符,可以用len()函数
len()
函数计算的是str
的字符数,如果换成bytes
,len()
函数就计算字节数
由于Python源代码也是一个文本文件,所以,当你的源代码中包含中文的时候,在保存源代码时,就需要务必指定保存为UTF-8编码。当Python解释器读取源代码时,为了让它按UTF-8编码读取,我们通常在文件开头写上这两行:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
第一行注释是为了告诉Linux/OS X系统,这是一个Python可执行程序,Windows系统会忽略这个注释;
第二行注释是为了告诉Python解释器,按照UTF-8编码读取源代码,否则,你在源代码中写的中文输出可能会有乱码。
申明了UTF-8编码并不意味着你的.py
文件就是UTF-8编码的,必须并且要确保文本编辑器正在使用UTF-8 without BOM编码
在Python中,采用的格式化方式和C语言是一致的,用%
实现
用%%
来表示一个%
二、 list与tuple
列表:list
1、 可以往list中追加元素到末尾 .append('Adam')
2、 可以用-1
做索引
3、 用len()
函数可以获得list元素的个数
4、 可以把元素插入到指定的位置,比如索引号为1
的位置 .insert(1, 'Jack')
5、 删除list末尾的元素,用pop()
方法
6、 删除指定位置的元素,用pop(i)
方法,其中i
是索引位置
7、 把某个元素替换成别的元素,可以直接赋值给对应的索引位置
8、 list里面的元素的数据类型也可以不同
元组:tuple
1、 tuple和list非常类似,但是tuple一旦初始化就不能修改
2、 没有append(),insert()这样的方法
3、 获取元素的方法和list是一样的
4、 当你定义一个tuple时,在定义的时候,tuple的元素就必须被确定下来
5、 tuple的陷阱:只有1个元素的tuple定义时必须加一个逗号,
,来消除歧义
三、条件判断
1、
age =
3
ifage >=
18:
(
'your age is', age)
(
'adult')
else:
(
'your age is', age)
(
'teenager')
2、elif
是else if
的缩写
3、
if
判断条件还可以简写,比如写:
if x:
(
'True')
只要x
是非零数值、非空字符串、非空list等,就判断为True
,否则为False
4、input()
返回的数据类型是str
,str
不能直接和整数比较,必须先把str
转换成整数。Python提供了int()
函数 int()
函数发现一个字符串并不是合法的数字时就会报错
四、 循环
1、
Python的循环有两种,一种是for...in循环,依次把list或tuple中的每个元素迭代出来,看例子:
names = [
'Michael',
'Bob',
'Tracy']
forname
innames:
print(name)
2、range()
函数,可以生成一个整数序列,再通过list()
函数可以转换为list。比如range(5)
生成的序列是从0开始小于5的整数
3、第二种循环是while循环,只要条件满足,就不断循环,条件不满足时退出循环
sum =
0
n =
99
whilen >
0:
sum = sum + n
n = n -
2
print(sum)
五、 Dict 和 set
1、Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。
2、用Python写一个dict如下:d = {'Michael': 95, 'Bob': 75,'Tracy': 85}
3、d['Adam'] = 67
4.、通过in
判断key是否存在 'Thomas' in d
5、dict内部存放的顺序和key放入的顺序是没有关系的
6、 通过dict提供的get方法,如果key不存在,可以返回None,或者自己指定的value
7、 要删除一个key,用pop(key)
方法,对应的value也会从dict中删除
和list比较,dict有以下几个特点:
1. 查找和插入的速度极快,不会随着key的增加而增加;
2. 需要占用大量的内存,内存浪费多。
而list相反:
1. 查找和插入的时间随着元素的增加而增加;
2. 占用空间小,浪费内存很少。
8、 dict的key必须是不可变对象 哈希算法(Hash)
1、 key不能重复,所以,在set中,没有重复的key
2、 s = set([1, 2, 3])
3、 传入的参数[1, 2, 3]是一个list,而显示的{1, 2, 3}只是告诉你这个set内部有1,2,3这3个元素,显示的顺序也不表示set是有序的。重复元素在set中自动被过滤。
4、 通过add(key)
方法可以添加元素到set中,可以重复添加,但不会有效果
5、 通过remove(key)
方法可以删除元素
6、 两个set可以做数学意义上的交集、并集等操作
7、
>>>s1 = set([
1,
2,
3])
>>>s2 = set([
2,
3,
4])
>>> s1 & s2
{
2,
3}
>>> s1 | s2
{
1,
2,
3,
4}
7、 set和dict的唯一区别仅在于没有存储对应的value,但是,set的原理和dict一样,所以,同样不可以放入可变对象,因为无法判断两个可变对象是否相等,也就无法保证set内部“不会有重复元素”。试试把list放入set,看看是否会报错
8、 对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新的对象并返回,这样,就保证了不可变对象本身永远是不可变的
六、 函数
1、 可以在交互式命令行通过help(abs)
查看abs
函数的帮助信息
2、 函数名其实就是指向一个函数对象的引用,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”
3、 定义一个函数要使用def
语句,依次写出函数名、括号、括号中的参数和冒号:
,然后,在缩进块中编写函数体,函数的返回值用return
语句返回
4、
defmy_abs(x):
if
x >=
0:
return
x
else
:
return
-x
如果没有return
语句,函数执行完毕后也会返回结果,只是结果为None
4、 如果你已经把my_abs()
的函数定义保存为abstest.py
文件了,那么,可以在该文件的当前目录下启动Python解释器,用from abstest import my_abs
来导入my_abs()
函数,注意abstest
是文件名(不含.py
扩展名)
5、 如果想定义一个什么事也不做的空函数,可以用pass
语句 缺少了pass
,代码运行就会有语法错误
6、
让我们修改一下my_abs
的定义,对参数类型做检查,只允许整数和浮点数类型的参数。数据类型检查可以用内置函数isinstance()
实现:
defmy_abs(x):
ifnot
isinstance(x, (int, float)):
raise
TypeError(
'bad operand type')
if
x >=
0:
return
x
else
:
return
-x
添加了参数检查后,如果传入错误的参数类型,函数就可以抛出一个错误:
>>> my_abs('A')
Traceback (most recent call last):
File "
<stdin>", line 1, in
<module>
File "
<stdin>", line 3, in my_abs
TypeError: bad operand type
7、
函数可以返回多个值吗?答案是肯定的。
比如在游戏中经常需要从一个点移动到另一个点,给出坐标、位移和角度,就可以计算出新的新的坐标:
import math
defmove(x, y, step, angle=0):
nx = x + step * math.cos(angle)
ny = y - step * math.sin(angle)
return
nx, ny
import math
语句表示导入math
包
返回值是一个tuple!但是,在语法上,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值,所以,Python的函数返回多值其实就是返回一个tuple,但写起来更方便
小结
定义函数时,需要确定函数名和参数个数;
如果有必要,可以先对参数的数据类型做检查;
函数体内部可以用return
随时返回函数结果;
函数执行完毕也没有return
语句时,自动return None
。
函数可以同时返回多个值,但其实就是一个tuple。
函数的参数
1、默认参数
defpower(x, n=2):
s =
1
while
n >
0:
n = n -
1
s = s * x
return
s
必选参数在前,默认参数在后,否则Python的解释器会报错(思考一下为什么默认参数不能放在必选参数前面)
2、默认参数必须指向不变对象!
3、
要修改上面的例子,我们可以用None
这个不变对象来实现:
defadd_end(L=None):
if
L
isNone:
L = []
L.append(
'END')
return
L
4、
我们把函数的参数改为可变参数:
defcalc(*numbers):
sum =
0
for
n
innumbers:
sum = sum + n * n
return
sum
定义可变参数和定义一个list或tuple参数相比,仅仅在参数前面加了一个*
号。在函数内部,参数numbers
接收到的是一个tuple,因此,函数代码完全不变。但是,调用该函数时,可以传入任意个参数,包括0个参数
5、
这种写法当然是可行的,问题是太繁琐,所以Python允许你在list或tuple前面加一个*
号,把list或tuple的元素变成可变参数传进去:
>>>nums = [
1,
2,
3]
>>> calc(*nums)
6、 可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict
7、
defperson(name, age, **kw):
print(
'name:', name,
'age:', age,
'other:', kw)
8、、、、、、。。。。。。。。、、、、、
http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431752945034eb82ac80a3e64b9bb4929b16eeed1eb9000
小结
Python的函数具有非常灵活的参数形态,既可以实现简单的调用,又可以传入非常复杂的参数。
默认参数一定要用不可变对象,如果是可变对象,程序运行时会有逻辑错误!
要注意定义可变参数和关键字参数的语法:
*args
是可变参数,args接收的是一个tuple;
**kw
是关键字参数,kw接收的是一个dict。
以及调用函数时如何传入可变参数和关键字参数的语法:
可变参数既可以直接传入:func(1, 2, 3)
,又可以先组装list或tuple,再通过*args
传入:func(*(1, 2, 3))
;
关键字参数既可以直接传入:func(a=1, b=2)
,又可以先组装dict,再通过**kw
传入:func(**{'a': 1, 'b': 2})
。
使用*args
和**kw
是Python的习惯写法,当然也可以用其他参数名,但最好使用习惯用法。
命名的关键字参数是为了限制调用者可以传入的参数名,同时可以提供默认值。
定义命名的关键字参数不要忘了写分隔符*
,否则定义的将是位置参数。
尾递归
汉诺塔
#!/usr/bin/env python3 |
# -*- coding: utf-8 -*- |
# 利用递归函数计算阶乘 |
# N! = 1 * 2 * 3 * ... * N |
deffact(n): |
if n ==1: |
return1 |
return n * fact(n-1) |
print('fact(1) =', fact(1)) |
print('fact(5) =', fact(5)) |
print('fact(10) =', fact(10)) |
# 利用递归函数移动汉诺塔: |
defmove(n, a, b, c): |
if n ==1: |
print('move', a, '-->', c) |
return |
move(n-1, a, c, b) |
print('move', a, '-->', c) |
move(n-1, b, a, c) |
move(4, 'A', 'B', 'C') |