一、版本切换
mac os
自带 Pyhton 2.7
,如想使用 Python 3
,请前往官网自行下载安装
官网地址
python3 英文文档
python3 中文文档
终端输入 python
可以看到版本号等信息
终端输入 python3
设置别名
1 | $ vi ~/.bash_profile |
二、输入和输出
Python
的交互式命令行
- 在终端键入
python
进入交互模式 exit()
退出交互模式
print()
输出
打印字符串
1 | # 多个字符串,用逗号“,”隔开,就可以连成一串输出。遇到逗号“,”会输出一个空格。 |
打印整数
1 | >>> print('100 + 200 =', 100 + 200) |
转义符
1 | >>> print('\\\t\\') |
多行
1 | #'''...'''的格式表示多行内容 |
混合
1 | >>> print(r'''hello,\n |
input()
输入
1 | >>> name = input() |
三、数据类型
整数
1
,100
,-8080
,0
- 整数的除法
1
2
3
4
5
6
7
8
9
10
11
12
13>>> 10 / 3
# 3.3333333333333335
>>> 9 / 3
# 3.0
# 地板除
>>> 10 // 3
# 3
# 余数运算
>>> 10 % 3
# 1
浮点数
1.23
乘以10
的9
次方 就是1.23e9
0.000012
可以写成1.2e-5
字符串
1 | >>> print('I\'m \"OK\"!') |
布尔值
True
False
布尔值可以用 and
、or
和 not
运算
1 | >>> True and False |
条件判断
1 | if age >= 18: |
空值 None
常量
1 | // 常量就是不能变的变量 |
数据类型转换
1 | >>> int('123') |
isinstance()
数据类型检查
1 | >>> isinstance('abc', str) |
四、变量
动态语言
1 | a = 1 |
字符串 replace()
方法
1 | >>> a = 'abc' |
静态语言
1 | int a = 123; // a是整数类型变量 |
理解变量在计算机内存中的表示
1 | a = 'ABC' |
- 在内存中创建了一个’ABC’的字符串
- 在内存中创建了一个名为
a
的变量,并把它指向'ABC'
重点
1 | a = 'ABC' |
五、list
和 tuple
list
Python内置的一种数据类型是列表, list是一种有序的集合
1 | >>> classmates = ['Michael', 'Bob', 'Tracy'] |
索引
1 | >>> classmates[0] |
len
1 | >>> len(classmates) |
append
末尾追加元素
1 | >>> classmates.append('Adam') |
insert
在指定位置插入
1 | >>> classmates.insert(1, 'Jack') |
pop
删除
1 | # 末尾删除 |
替换元素
1 | >>> classmates[1] = 'Sarah' |
sort()
排序
1 | >>> a = ['c', 'b', 'a'] |
tuple
tuple
和 list
非常类似,但是 tuple
一旦初始化就不能修改
1 | >>> classmates = ('Michael', 'Bob', 'Tracy') |
定义一个只有 1
个元素的 tuple
1 | >>> t = (1) |
可变的 tuple
1 | >>> t = ('a', 'b', ['A', 'B']) |
六、循环
for x in ...
1 | names = ['Michael', 'Bob', 'Tracy'] |
range()
1 | # 生成一个整数序列 |
while
循环
1 | sum = 0 |
break
break语句可以提前退出循环
1 | n = 1 |
continue
跳过当前的这次循环,直接开始下一次循环
1 | n = 0 |
要特别注意
- 不要滥用break和continue语句。break和continue会造成代码执行逻辑分叉过多,容易出错。大多数循环并不需要用到break和continue语句,上面的两个例子,都可以通过改写循环条件或者修改循环逻辑,去掉break和continue语句。
七、dict
和 set
1 | >>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85} |
dist
in
判断 key
是否存在
1 | >>> 'Thomas' in d |
get()
1 | # get() 函数返回指定键的值,如果值不在字典中返回默认值 |
pop()
删除 key
1 | >>> d.pop('Bob') |
dict内部存放的顺序和key放入的顺序是没有关系的
和 list
比较,dict
有以下几个特点
- 查找和插入的速度极快,不会随着key的增加而变慢
- 需要占用大量的内存,内存浪费多
list
相反dict
是用空间来换取时间的一种方法
set
set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。
创建
1 | >>> s = set([1, 2, 3]) |
重复元素在 set
中自动被过滤
1 | >>> s = set([1, 1, 2, 2, 3, 3]) |
add(key)
添加元素
1 | >>> s.add(4) |
remove(key)
删除元素
1 | >>> s.remove(4) |
交集、并集
1 | >>> s1 = set([1, 2, 3]) |
八、函数
调用函数
abs()
1 | >>> abs(100) |
max()
1 | >>> max(1, 2) |
min()
1 | >>> max(1, 2) |
$ filter(function, iterable)
def is_odd(n):
return n % 2 == 1
newlist = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(newlist)
[1, 3, 5, 7, 9]
python2中返回的是过滤后的列表list, 而python3中返回到是一个filter类
1 | ``` |
func=lambda x:x+1
print(func(1))
2
foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]
print (list(filter(lambda x: x % 3 == 0, foo)))
[18, 9, 24, 12, 27]
1 | ### 定义函数 |
def my_abs(x):
if x >= 0:
return x
else:
return -x1
2##### 引入函数
你已经把my_abs()的函数定义保存为abstest.py文件了
from abstest import my_abs1
2##### 空函数
如果想定义一个什么事也不做的空函数,可以用pass语句:
def nop():
pass1
2pass语句什么都不做,那有什么用?实际上pass可以用来作为占位符,比如现在还没想好怎么写函数的代码,就可以先放一个pass,让代码能运行起来。
##### 参数检查
def my_abs(x):
if not isinstance(x, (int, float)):
raise TypeError(‘bad operand type’)
if x >= 0:
return x
else:
return -x1
##### 返回多个值
import math
def move(x, y, step, angle=0):
nx = x + step math.cos(angle)
ny = y - step math.sin(angle)
return nx, ny
x, y = move(100, 100, 60, math.pi / 6)
print(x, y)
151.96152422706632 70.0
但其实这只是一种假象,Python函数返回的仍然是单一值:
r = move(100, 100, 60, math.pi / 6)
print(r)
(151.96152422706632, 70.0)
1
2 ### 函数的参数
##### 位置参数
def power(x, n):
s = 1
while n > 0:
n = n - 1
s = s * x
return s
power(5, 2)
25
1 | ##### 默认参数 |
def power(x, n=2):
s = 1
while n > 0:
n = n - 1
s = s * x
return s
power(5)
25
1 | - 注意 |
def add_end(L=[]):
L.append(‘END’)
return L
add_end()
[‘END’]
add_end()
[‘END’, ‘END’]
1 | - Python函数在定义的时候,默认参数L的值就被计算出来了,即[],因为默认参数L也是一个变量,它指向对象[],每次调用该函数,如果改变了L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了。 |
def add_end(L=None):
if L is None:
L = []
L.append(‘END’)
return L
add_end()
[‘END’]
add_end()
[‘END’]
1 | ##### 可变参数 |
def calc(numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
calc([1, 2, 3])
14
calc((1, 3, 5, 7))
84
1 | - 可变参数 |
def calc(numbers):
sum = 0
for n in numbers:
sum = sum + n n
return sum
calc(1, 2)
5
calc()
0
nums = [1, 2, 3]
calc(*nums)
14
1 | ##### 关键字参数 |
def person(name, age, **kw):
print(‘name:’, name, ‘age:’, age, ‘other:’, kw)
person(‘Michael’, 30)
name: Michael age: 30 other: {}
person(‘Bob’, 35, city=’Beijing’)
name: Bob age: 35 other: {‘city’: ‘Beijing’}
person(‘Adam’, 45, gender=’M’, job=’Engineer’)
name: Adam age: 45 other: {‘gender’: ‘M’, ‘job’: ‘Engineer’}
extra = {‘city’: ‘Beijing’, ‘job’: ‘Engineer’}
person(‘Jack’, 24, **extra)
name: Jack age: 24 other: {‘city’: ‘Beijing’, ‘job’: ‘Engineer’}
1 | ##### 命名关键字参数 |
def person(name, age, *, city, job):
print(name, age, city, job)
person(‘Jack’, 24, city=’Beijing’, job=’Engineer’)
Jack 24 Beijing Engineer
1 | ##### 参数组合 |
def f1(a, b, c=0, *args, **kw):
print(‘a =’, a, ‘b =’, b, ‘c =’, c, ‘args =’, args, ‘kw =’, kw)
def f2(a, b, c=0, *, d, **kw):
print(‘a =’, a, ‘b =’, b, ‘c =’, c, ‘d =’, d, ‘kw =’, kw)1
2
3
4
5
6
7
8
9
10
11```
>>> f1(1, 2)
a = 1 b = 2 c = 0 args = () kw = {}
>>> f1(1, 2, c=3)
a = 1 b = 2 c = 3 args = () kw = {}
>>> f1(1, 2, 3, 'a', 'b')
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {}
>>> f1(1, 2, 3, 'a', 'b', x=99)
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99}
>>> f2(1, 2, d=99, ext=None)
a = 1 b = 2 c = 0 d = 99 kw = {'ext': None}
1 | >>> args = (1, 2, 3, 4) |
递归函数
1 | def fact(n): |
栈
- 递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。
- 使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。可以试试fact(1000):
1 | >>> fact(1000) |
- 解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的。
尾递归
1 | def fact(n): |
1 | >>> fact(5) |