通过print()打印
python的标准数据类型:
- Number(数字)
- String(字符串)
- List(列表)
- Tuple(元组)
- Set(集合)
- Dictionary(字典)
不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);
可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。
字符串
字符串中如果存在"" 或者 '' 可以通过 / 进行转义
多行字符串可以通过 '''...''' 格式表示
多行字符串 '''...''' 还可以在前面加上r使用
print(r'''hello,\n
world''')
===》 hello,\n
world
ord() 获取字符的ascii码
chr() 把编码转换为对应的字符
'\u4e2d\u6587' 也可以直接通过此种形式获取字符
bytes类型的数据用带b前缀的单引号或双引号表示
以Unicode表示的str通过encode()方法可以编码为指定的bytes
'ABC'.encode('ascii') => b'ABC'
'中文'.encode('utf-8') => b'\u4e2d\u6587'
'中文'.encode('ascii') => 报错
!!! 纯英文的str可以用ASCII编码为bytes,内容是一样的,含有中文的str可以用UTF-8编码为bytes。含有中文的str无法用ASCII编码,因为中文编码的范围超过了ASCII编码的范围
decode() 把bytes变为str (从网络或磁盘上读取了字节流,那么读到的数据就是bytes)
如果bytes中包含无法解码的字节,decode()方法会报错
b'\xe4\xb8\xad\xff'.decode('utf-8') => 报错
如果bytes中只有一小部分无效的字节,可以传入errors='ignore'忽略错误的字节
b'\xe4\xb8\xad\xff'.decode('utf-8', errors='ignore') => '中'
len() 计算str/bytes包含多少个字符
len('中文'.encode('utf-8')) => 6
len('中文') => 2
replace() 字符串替换
a = 'abc'
a.replace('a', 'A')
字符串格式化
-
用%实现, 不知道用什么,直接用%s,可以将任意类型转化为字符串输出
‘Hi, %s, you have $%d.’ % (‘Michael’, 1000000) => ‘Hi, Michael, you have $1000000.’
(ps: %d 整数 %f 浮点数 %s 字符串 %x 十六进制整数)
print(’%2d-%02d’ % (3, 1)) => 3-01
print(’%.2f’ % 3.1415926) => 3.14
字符串里面的%是一个普通字符怎么办?这个时候就需要转义,用%%来表示一个%
‘growth rate: %d %%’ % 7 => ‘growth rate: 7 %’ -
format() 格式化字符串
‘Hello, {0}, 成绩提升了 {1:.1f}%’.format(‘小明’, 17.125) => ‘Hello, 小明, 成绩提升了 17.1%’
数字类型
布尔值 存在 True 和 False 两个值,通过 and、or和not 进行运算
True and True => True
True or False => True
not True => False
空值 None 与0不同,None是无意义的空值
变量名必须是大小写英文、数字和_的组合,且不能用数字开头 a = 1;
常量 通常用全部大写的变量名表示
int() 转化为整数,不是合法的数字,就报错
input() 读取用户的输入
s = input('birth: ')
birth = int(s)
if birth < 2000:
print('00前')
else:
print('00后')
python 中存在两种除法 / (得到的是浮点数)和 // (得到的是整数)
10 / 3 => 3.33333……
10 // 3 => 3 (只取整数部分)
10 % 3 => 1 (取余数)
!!! python 整数没有限制 浮点数也没有限制, 但是超出一定范围就直接显示inf
列表 (list) 数组类似,存在二维,三维 …… classmates[1][0]
classmates = ['a', 'b', 'c'];
classmates => ['a', 'b', 'c']
len(classmates) => 3
classmates[0] / classmates[-3] => 'a'
classmates[1] / classmates[-2] => 'b'
classmates[2] / classmates[-1] => 'c'
classmates.append('d') => ['a', 'b', 'c', 'd']
classmates.insert(1, 'e') => ['a', 'e', b', 'c', 'd']
classmates.pop() => ['a', 'e', b', 'c']
classmates.pop(1) => ['a', 'b', 'c']
classmates[1] = 'd' => ['a', 'd', 'c']
classmetas * 2 => 输出两次
append(str) 列表后加一个元素
insert(i, str) 指定位置添加元素, i 为索引
pop(i) 删除列表中元素, 如果i不传,删除最后一个,传i删除索引指定元素 ,换回删除元素
sort() 排序
元祖 (tuple) 一旦初始化就不能修改,所以代码更安全
classmates = ('a', 'b', 'c')
classmetas * 2 => 输出两次
有1个元素的tuple定义时必须加一个逗号, => classmates = (1,)
字典 (dict) 使用键-值(key-value)存储, 具有极快的查找速度
classmetas = {'a': 95, 'b': 75, 'c': 85}
classmetas['a'] => 95
classmetas['d'] = 59 => 添加一个键值对
classmetas['e'] => 报错,不存在
'e' in classmetas => 判断是否在字典中
classmetas.get('e', -1) => 判断是否在字典中,第二个参数自定义返回内容,不传则返回None
classmetas.pop('a') => 删除key值为a的元素
get(key, content) 判断key是否在字典中,并可以定义返回内容
pop(key) 删除key值对应的元素,返回key值对应的value
!!! dict中key值不可变
set 无序和无重复元素的集合,只存在key,不存储value ,key不重复
创建一个set,需要提供一个list作为输入集合
s = set([1, 2, 3]) => {1, 2, 3}
s = set([1, 1, 3, 2, 4]) => {1, 2, 3, 4}
s.add(4)
s.remove(4)
add(key) 添加元素到set中,可以重复添加,但不会有效果
remove(key) 删除元素
两个set可以做数学意义上的交集、并集等操作
s1 = set([1, 2, 3, 4, 5])
s2 = set([3, 4, 5, 6, 7])
s1 & s2 => {3, 4, 5} 交集
s1 | s2 => {1, 2, 3, 4, 5, 6, 7} 并集
s1 - s2 => {1, 2} 差集
s1 ^ s2 => {1, 2, 6, 7} 不同时存在
条件判断 if … elif … else,存在缩进
age = 20
if age >= 18:
print('adult')
elif age >= 6:
print('teenager')
else:
print('kid')
!!!注意不要少写了冒号 :
只要x是非零数值、非空字符串、非空list等, 可以简写为:
if x:
print('True')
循环
for…in…
range() 生成一个整数序列,可以通过list()函数可以转换为list
list(range(5)) => [0, 1, 2, 3, 4]
while
sum = 0
n = 99
while n > 0:
sum = sum + n
n = n - 2
print(sum)
在循环中,break语句可以提前退出循环; 可以通过continue语句,跳过当前的这次循环,直接开始下一次循环
函数
函数名其实就是指向一个函数对象的引用,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”
a = abs
a(-1)
isinstance() 数据类型检查 isinstance(x, (int, float))
数学类型:
abs() 获取绝对值 abs(-20)
max() 获取最大值 max(1,2,4,7,100)
sqrt() 计算平方根
数据类型转换:
int() int('12') => 12 int(12.89) => 12
float() float(12) => 12.0 float('12.34') => 12.34
str() str(1.23) => '1.23' str(100) => '100'
bool() bool(1) => True bool('') => False
定义函数 def 依次写出函数名、括号、括号中的参数和冒号: , return 返回值
def my_abs(x):
if x >= 0:
return x
else:
return -x
如果函数没有return,也会返回结果None ,return None可以简写为return
return 可以返回多个值 return x,y 实际上返回一个tuple (x,y)
!!! from 文件名 import 模块
import math语句表示导入math包,并允许后续代码引用math包里的sin、cos等函数。
空函数 用pass作为占位符,保证正常运行,pass也可以在别的语句中使用,比如if
def nop():
pass
函数参数
默认参数 !!!必须指向不变对象!
def power(x, n=2):
可变参数 允许你传入0个或任意个参数, 接收的是一个tuple/list
在前面加 *
定义: def calc(*numbers):
使用: nums = [1, 2, 3]
calc(*nums)
关键字参数
关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
person('Michael', 30)
==> name: Michael age: 30 other: {}
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'}
!!!此处kw获取的是extra的一个拷贝,不会影响其他函数
命名关键字参数
如果需要限制关键字参数的名字,就可以用命名关键字参数
命名关键字参数需要一个特殊分隔符*,*后面的参数被视为命名关键字参数
def person(name, age, *, city, job):
print(name, age, city, job) // 只接收city和job作为关键字参数
如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*
def person(name, age, *args, city, job):
print(name, age, args, city, job)
调用命名关键字参数必须写参数名,否则报错
person('Jack', 24, city='Beijing', job='Engineer')
命名关键字参数可以有缺省值
def person(name, age, *, cit='beijing', job):
print(name, age, args, city, job)
person('Jack', 24, job='Engineer')
参数组合
在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
对于任意函数,都可以通过类似func(*args, **kw)的形式调用它,无论它的参数是如何定义的
递归函数
通过尾递归解决递归溢出问题
尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式
!!!大多数编程语言没有针对尾递归做优化,Python解释器也没有做优化,所以,即使把下面的fact(n)函数改成尾递归方式,也会导致栈溢出
def fact(n):
if n==1:
return 1
return n * fact(n - 1)
切片
lists = [1, 2, 3, 4, 5, 6, 7]
取前三:
arr = []
n = 3
for i in range(n):
arr.append(lists[i])
lists[0:3] //不包含索引为3的、
lists[:3]
lists[1:3] // [2,3]
lists[-2:] // [6,7]
lists[-2:-1] // [7]
lists[:4:2] //[2, 4] 前四个数每两个取一次
lists[::3] // [3,6] 所有数,每三个取一次
lists[:] //原样复制
list和tuple一样,只是tuple不可变,当执行切片之后lists变化为切之后的
字符串也可以看成是list,也可以进行切片
迭代
任何可迭代对象都可以作用于for循环,包括我们自定义的数据类型,只要符合迭代条件,就可以使用for循环
d = {a : 1, b : 2, c : 3}
for k in d
for v in d.values()
for k, v in d.items()
通过collections模块的Iterable类型判断一个对象是否可以迭代
isinstance('abc', Iterable) => True
enumerate函数可以把一个list变成索引-元素对
for i, value in enumerate(['A', 'B', 'C'])
列表生成式
list(range(1,11)) => [1, …… ,10, 11]
[x * x for x in range(1, 11)]
for循环后面还可以加上if判断
[x * x for x in range(1, 11) if x % 2 == 0]
两层循环
[m + n for m in 'ABC' for n in 'XYZ']
列出当前目录下的所有文件和目录名
import os
[d for d in os.listdir('.')]
循环两个变量
[k + '=' + v for k, v in d.items()]
所有字符串变成小写
L = ['Hello', 'World', 'IBM', 'Apple']
[s.lower() for s in L]
添加if类型判断
L = ['Hello', 'World', 'IBM', 'Apple', 18, None]
[s.lower() for s in L if isinstance(s, str)]
生成器 generator
与列表生成式不同的是一个[]一个()
l = [x * x for x in range(1, 11)] 列表生成式
g = (x * x for x in range(10)) 生成器
generator函数定义中包含yield关键字
执行顺序:generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行
通过next()函数获得generator的下一个返回值
但基本上不会用next()来获取下一个返回值,而是直接使用for循环来迭代
for x in g:
print(x)
for循环调用generator时,拿不到generator的return语句的返回值。
如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return 'done'
g = fib(6)
while True:
try:
x = next(g)
print('g:', x)
except StopIteration as e:
print('Generator return value:', e.value)
break
!!!python的赋值语句 a,b,c = 0,0,1 相当于 t = (0,0,1) a=t[0] b=t[1] c=t[2]
!!!直接作用于for循环的数据类型有以下几种:
1. 集合数据类型,如list、tuple、dict、set、str等;
2. generator,包括生成器和带yield的generator function。
迭代器
可以直接作用于for循环的对象统称为可迭代对象:Iterable
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator
Iterator表示一个惰性计算的序列, 只有需要返回下一个数据的时候才开始计算
可以使用isinstance()判断一个对象是否是Iterable对象/Iterator对象
from collections import Iterable
isinstance([], Iterable)
isinstance('abc', Iterable)
isinstance((x for x in range(10)), Iterator)
生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。
把list、dict、str等Iterable变成Iterator可以使用iter()函数.
高阶函数
函数本身也可以赋值给变量,即:变量可以指向函数
f = abs
f -> 求绝对值函数 f(-10) -> 10
由于abs函数实际上是定义在import builtins模块中的,所以要让修改abs变量的指向在其它模块也生效,要用import builtins; builtins.abs = 10。
函数参数传函数 -> 高阶函数
def add(x, y, f):
return f(x) + f(y)
map() 接收两个参数,一个是函数,一个是Iterable, 返回值是Iterator
def f(x):
return x * x
r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
list(r)
reduce() 必须接收两个参数,一个是函数,一个是序列,
reduce把结果继续和序列的下一个元素做累积计算
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
filter() 接收一个函数和一个序列, 返回值是Iterator
把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素
sorted()
可以接收一个key函数来实现自定义的排序
sorted([36, 5, -12, 9, -21], key=abs)
sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower) //正向,小写排序
sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True) //反向
返回函数
闭包(返回函数不要引用任何循环变量,或者后续会发生变化的变量)
未完待续