参考廖雪峰的官方网站https://www.liaoxuefeng.com/wiki/1016959663602400
东西很全,如果能静下心来学是有很不错的。
文章目录
数据类型
- 整数:任意整数和16进制,eg 1,100,-80,0,0xff00,0xa5b4
- 浮点数:1.23,3.14,-99.1,1.23e9,1.2e-5
- 字符串:
- 单引号’'或者双引号"",如果单引号也是字符,那么就用双引号括起来,eg “i’m ok!”
- 如果字符中既包括单引号,也包括双引号,可以用转义字符\来标识。'I ‘m “ok”’---->I’m “ok”
- \本身也有意思,所以如果字符串中包含\,就用\来表示
- 将字符串放在r’字符串’中,则表示全部不转义
- 如果换行都用\n,就太不方便了,可以在字符在字符前加…;eg:…line1…line2
- 布尔值:True,False(注意大小写),有and,or,not运算方式
- 空值:None,一个特殊的空值,与0不同
- 变量:可以是任意数据类型
- 变量名必须是大小写英文,数字,_的组合,并且不能用数字开头
- 常量:写法上来说通常用全部大写来表示常量PI=3.1415926,事实上他还是变量
- /除法,//整除
- python的整数是没有大小限制的,这点与java不同,浮点数也是,但过一定范围会表示为inf
字符编码
- 字符转编码:ord()
- 编码转字符:chr()
- ‘ABC’.encode(‘ascii’) 编码为指定的code
- b’\xe4\xb8\xad\xe6\x96\x87’.decode(‘utf-8’)
- len():统计str有多少个字符
- len(b’ABC’) 3
len(b’\xe4\xb8\xad\xe6\x96\x87’) 6
len(‘中文’.encode(‘utf-8’)) 6
所以:1个中文字符经过UTF-8编码后通常会占用3个字节,而1个英文字符只占用1个字节。 - 格式化字符串的方式:%d:整数,%f:浮点数,%s:字符串,%x:十六进制整数
- 当%是一个字符的时候,就用%%来表示一个%
‘Hello, %s’ % ‘world’ ‘Hello, world’
‘Hi, %s, you have $%d.’ % (‘Michael’, 1000000) ‘Hi, Michael, you have $1000000.’ - 另外一种格式化方式:format()
‘Hello, {0}, 成绩提升了 {1:.1f}%’.format(‘小明’, 17.125)
‘Hello, 小明, 成绩提升了 17.1%’
list
- python内置的一种数据结构,list是一种有序的集合,可以随时添加和删除其中的元素。
- classmates = [‘Michael’, ‘Bob’, ‘Tracy’]
- 用len()函数可以获得list元素的个数: len(classmates)
- 用索引来访问list中每一个位置的元素classmates[0],classmates[1],classmates[2],注意不要越界
- 取最后一个元素:classmates[-1]
- 可以往list中追加元素到末尾:classmates.append(‘Adam’)
- 也可以把元素插入到指定的位置:classmates.insert(1, ‘Jack’)
- 要删除list末尾的元素:classmates.pop()
- 要删除指定位置的元素:classmates.pop(1)
- list里面的元素的数据类型也可以不同: L = [‘Apple’, 123, True]
- list元素也可以是另一个list:
s = ['python', 'java', ['asp', 'php'], 'scheme']
p = ['asp', 'php']
s = ['python', 'java', p, 'scheme']
- 一个空的list:L = []
tuple
- tuple和list非常类似,但是tuple一旦初始化就不能修改
它也没有append(),insert()这样的方法,其他获取元素的方法和list是一样的
不可变的tuple有什么意义?因为tuple不可变,所以代码更安全。如果可能,能用tuple代替list就尽量用tuple。 - t = (1,)只有1个元素的tuple定义时必须加一个逗号
条件判断
注意不要少写了冒号
age = 3
if age >= 18:
print('adult')
elif age >= 6:
print('teenager')
else:
print('kid')
判断条件还可以简写
if x:
print('True')
循环
- 第一种
names = ['Michael', 'Bob', 'Tracy']
for name in names:
print(name)
Python提供一个range()函数,可以生成一个整数序列
list(range(5))
[0, 1, 2, 3, 4]
- 第二种
sum = 0
n = 99
while n > 0:
sum = sum + n
n = n - 2
print(sum)
- break
n = 1
while n <= 100:
if n > 10: # 当n = 11时,条件满足,执行break语句
break # break语句会结束当前循环
print(n)
n = n + 1
print('END')
- continue
n = 0
while n < 10:
n = n + 1
if n % 2 == 0: # 如果n是偶数,执行continue语句
continue # continue语句会直接继续下一轮循环,后续的print()语句不会执行
print(n)
dict
Python内置了字典:dict的支持,使用键-值(key-value)存储,具有极快的查找速度。
d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
d['Michael']
要避免key不存在的错误
一是通过in判断key是否存在:
'Thomas' in d
二是通过dict提供的get()方法:
d.get('Thomas')
要删除一个key:
d.pop('Bob')
dict的key必须是不可变对象
set
set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。
set可以去重复
add(key)添加
remove(key)删除
函数
abs():绝对值
max():最大值
int():数据类型转换
- 函数的定义:
在Python中,定义一个函数要使用def语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回。
def my_abs(x):
if x >= 0:
return x
else:
return -x
- 空函数
def nop():
pass
实际上pass可以用来作为占位符,比如现在还没想好怎么写函数的代码,就可以先放一个pass,让代码能运行起来
- 函数有多个返回值的时候,返回的是一个元组
函数的参数
位置参数
def power(x):
return x * x
参数x就是一个位置参数
默认参数
def power(x, n=2):
s = 1
while n > 0:
n = n - 1
s = s * x
return s
n=2就是一个默认参数
- 定义默认参数要牢记一点:默认参数必须指向不变对象
可变参数
可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。
- *nums表示把nums这个list的所有元素作为可变参数传进去。这种写法相当有用,而且很常见。
nums = [1, 2, 3]
calc(*nums)
- extra表示把extra这个dict的所有key-value用关键字参数传入到函数的kw参数,kw将获得一个dict,注意kw获得的dict是extra的一份拷贝,对kw的改动不会影响到函数外的extra。
extra = {'city': 'Beijing', 'job': 'Engineer'}
person('Jack', 24, **extra)
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
关键字参数
关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
>>> 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'}
命名关键字参数
- *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})
递归函数
def fact(n):
if n==1:
return 1
return n * fact(n - 1)
切片
>>> L = list(range(100))
>>> L
[0, 1, 2, 3, ..., 99]
>>> L[:10]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> L[10:20]
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> L[:10:2]
[0, 2, 4, 6, 8]
>>> L[::5]
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
tuple也是一种list,唯一区别是tuple不可变。因此,tuple也可以用切片操作,只是操作的结果仍是tuple:
>>> (0, 1, 2, 3, 4, 5)[:3]
(0, 1, 2)
迭代
python的for循环不仅可以用于list或者tuple上,还可以用于其他的迭代对象。
- 字典迭代
>>> d = {'a': 1, 'b': 2, 'c': 3}
>>> for key in d:
... print(key)
...
a
c
b
- 字符串迭代
>>> for ch in 'ABC':
... print(ch)
...
A
B
C
- 判断是否可迭代
>>> from collections import Iterable
>>> isinstance('abc', Iterable) # str是否可迭代
True
- 实现带索引下标的迭代:enumerate()函数
>>> for i, value in enumerate(['A', 'B', 'C']):
... print(i, value)
...
0 A
1 B
2 C
列表生成式
生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> list(range(1, 11))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
生成[1x1, 2x2, 3x3, …, 10x10]
>>> L = []
>>> for x in range(1, 11):
... L.append(x * x)
...
>>> L
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
还可以把要生成的元素放前面
>>> [x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
筛选出仅偶数的平方
>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]
>>> [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
生成器
把列表生成式的[]改成()就是一种
>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>
斐波拉契数列
def fib(max):
n, a, b = 0, 0, 1
while n < max:
print(b)
a, b = b, a + b
n = n + 1
return 'done'
利用生成器的斐波拉契数列(yield关键字)
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return 'done'
高阶函数
map()
map函数接收两个参数,一个是函数,一个是迭代器
>>> def f(x):
... return x * x
...
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
list所有数字转为字符串
>>> list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
['1', '2', '3', '4', '5', '6', '7', '8', '9']
reduce()
reduce主要用作累积计算
>>> from functools import reduce
>>> def add(x, y):
... return x + y
...
>>> reduce(add, [1, 3, 5, 7, 9])
25
filter()
过滤器
只保留奇数
def is_odd(n):
return n % 2 == 1
list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
# 结果: [1, 5, 9, 15]
去除空字符串
def not_empty(s):
return s and s.strip()
list(filter(not_empty, ['A', '', 'B', None, 'C', ' ']))
# 结果: ['A', 'B', 'C']
sort()
排序
>>> sorted([36, 5, -12, 9, -21])
[-21, -12, 5, 9, 36]
通过key值自定义排序
>>> sorted([36, 5, -12, 9, -21], key=abs)
[5, 9, -12, -21, 36]
反向排序
>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)
['Zoo', 'Credit', 'bob', 'about']
匿名函数lamda
>>> list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
[1, 4, 9, 16, 25, 36, 49, 64, 81]
装饰器
动态的新增函数的功能,又不会去修改函数本身
@log
def now():
print('2015-3-25')
偏函数
一个函数的某些参数给固定住(也就是设置默认值)也可以在函数调用时传入其他值
>>> import functools
>>> int2 = functools.partial(int, base=2)
>>> int2('1000000')
64
>>> int2('1010101')
85
>>> int2('1000000', base=10)
1000000
面向对象编程
私有变量
在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private)
class Student(object):
def __init__(self, name, score):
self.__name = name
self.__score = score
def print_score(self):
print('%s: %s' % (self.__name, self.__score))
但是如果外部代码要获取/修改name和score
class Student(object):
...
def get_name(self):
return self.__name
def get_score(self):
return self.__score
class Student(object):
...
def set_score(self, score):
self.__score = score
静态语言 vs 动态语言
对于静态语言(例如Java)来说,如果需要传入Animal类型,则传入的对象必须是Animal类型或者它的子类,否则,将无法调用run()方法。
动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。