python学习笔记(一)
list
Python内置的一种数据类型是列表:list。list是一种有序的集合,可以随时添加和删除其中的元素。
list定义:classmates = [‘Michael’, ‘Bob’, ‘Tracy’]
- len(classmates ): 取list元素个数
- []: 索引访问,[0]-第一个;[-1]-倒数第一个
- classmates .append(): 追加元素到末尾
- classmates .insert(i,’A’): 在索引i处插入元素A
- classmates .pop(): 删除list末尾元素;返回被删除元素
- classmates .pop(i): 删除索引i处的元素;返回被删除元素
- lsit 中元素数据类型可以不同,
L = ['Apple', 123, True] - list 中元素可以是另一个list,
s = ['python', 'java', ['asp', 'php'], 'scheme']
tuple
另一种有序列表叫元组:tuple。tuple和list非常类似,但是tuple一旦初始化就不能修改,比如同样是列出同学的名字:
classmates = ('Michael', 'Bob', 'Tracy'),现在,classmates这个tuple不能变了,它也没有append(),insert()这样的方法。其他获取元素的方法和list是一样的,你可以正常地使用classmates[0],classmates[-1],但不能赋值成另外的元素。
因为tuple不可变,所以代码更安全。如果可能,能用tuple代替list就尽量用tuple。
- 要定义一个只有1个元素的tuple, tuple(1)表示数字1,tuple(1,)表示元组。
if-else
if <条件判断1>:
<执行1>
elif <条件判断2>:
<执行2>
elif <条件判断3>:
<执行3>
else:
<执行4>
int()
int()函数可以将字符创转换为数字;当发现一个字符串并不是合法的数字时就会报错,程序就退出了。
循环
Python的循环有两种,一种是for…in循环,依次把list或tuple中的每个元素迭代出来;第二种循环是while循环,只要条件满足,就不断循环,条件不满足时退出循环。
- for…in:
sum = 0
for x in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
sum = sum + x
print(sum)
- while:
sum = 0
n = 99
while n > 0:
sum = sum + n
n = n - 2
print(sum)
dict
ython内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。
-
定义
>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85} >>> d['Michael'] 95 -
把数据放入dict的方法,除了初始化时指定外,还可以通过key放入:
>>> d['Adam'] = 67 >>> d['Adam'] 67 - 要避免key不存在的错误,有两种办法,
- 通过
in判断key是否存在:>>> 'Thomas' in d False - 通过dict提供的get方法,如果key不存在,可以返回None,或者自己指定的value:
>>> d.get('Thomas') >>> d.get('Thomas', -1)注意:返回
None的时候Python的交互式命令行不显示结果
- 通过
-
用
pop(key)方法,对应的value也会从dict中删除:>>> d.pop('Bob') 75 >>> d {'Michael': 95, 'Tracy': 85} -
和list比较,dict有以下几个特点:
- 查找和插入的速度极快,不会随着key的增加而增加;
- 需要占用大量的内存,内存浪费多。
set
set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。
-
要创建一个set,需要提供一个list作为输入集合:
>>> s = set([1, 2, 3]) >>> s set([1, 2, 3]) -
重复元素在set中自动被过滤:
>>> s = set([1, 1, 2, 2, 3, 3]) >>> s set([1, 2, 3]) -
通过
add(key)方法可以添加元素到set中,可以重复添加,但不会有效果:>>> s.add(4) >>> s set([1, 2, 3, 4]) >>> s.add(4) >>> s set([1, 2, 3, 4]) -
通过
remove(key)方法可以删除元素:>>> s.remove(4) >>> s set([1, 2, 3]) -
两个set可以做数学意义上的交集、并集等操作:
>>> s1 = set([1, 2, 3]) >>> s2 = set([2, 3, 4]) >>> s1 & s2 set([2, 3]) >>> s1 | s2 set([1, 2, 3, 4])
函数
定义函数
定义一个函数要使用
def语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回。
def my_abs(x):
if x >= 0:
return x
else:
return -x
-
空函数: 如果想定义一个什么事也不做的空函数,可以用
pass语句:def nop(): pass -
类型检查: 用内置函数
isinstance()实现:def my_abs(x): if not isinstance(x, (int, float)): raise TypeError('bad operand type') if x >= 0: return x else: return -x -
返回多个值
-
python 可以返回多个值:
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的饭后值任然是单一的,是一个tuple。
>>> r = move(100, 100, 60, math.pi / 6) >>> print(r) (151.96152422706632, 70.0)
-
python 可以返回多个值:
-
函数参数: Python的函数定义非常简单,但灵活度却非常大。除了正常定义的必选参数外,还可以使用默认参数、可变参数和关键字参数,使得函数定义出来的接口,不但能处理复杂的参数,还可以简化调用者的代码。
-
默认参数
def power(x, n=2): s = 1 while n > 0: n = n - 1 s = s * x return s必选参数在前,默认参数在后,否则Python的解释器会报错
-
默认参数很有用,但使用不当,也会掉坑里。默认参数有个最大的坑,演示如下:
-
先定义一个函数,传入一个list,添加一个
END再返回:def add_end(L=[]): L.append('END') return L -
当你正常调用时,结果似乎不错:
>>> add_end([1, 2, 3]) [1, 2, 3, 'END'] >>> add_end(['x', 'y', 'z']) ['x', 'y', 'z', 'END']
-
当你使用默认参数调用时,一开始结果也是对的:
>>> add_end() ['END'] -
但是,再次调用
add_end()时,结果就不对了:>>> add_end() ['END', 'END'] >>> add_end() ['END', 'END', 'END']
很多初学者很疑惑,默认参数是
[],但是函数似乎每次都“记住了”上次添加了'END'后的list。原因解释如下:Python函数在定义的时候,默认参数
L的值就被计算出来了,即[],因为默认参数L也是一个变量,它指向对象[],每次调用该函数,如果改变了L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了。所以,定义默认参数要牢记一点:默认参数必须指向不变对象!
-
先定义一个函数,传入一个list,添加一个
-
可变参数
-
要定义出这个函数,我们必须确定输入的参数。由于参数个数不确定,我们首先想到可以把a,b,c……作为一个list或tuple传进来,这样,函数可以定义如下:
def calc(numbers): sum = 0 for n in numbers: sum = sum + n * n return sum >>> calc([1, 2, 3]) 14 -
我们把函数的参数改为可变参数:
def calc(*numbers): sum = 0 for n in numbers: sum = sum + n * n return sum定义可变参数和定义一个list或tuple参数相比,仅仅在参数前面加了一个
*号。在函数内部,参数numbers接收到的是一个tuple,因此,函数代码完全不变。但是,调用该函数时,可以传入任意个参数,包括0个参数:>>> calc(1, 2) 5
-
要定义出这个函数,我们必须确定输入的参数。由于参数个数不确定,我们首先想到可以把a,b,c……作为一个list或tuple传进来,这样,函数可以定义如下:
-
关键字参数:
-
关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
def person(name, age, **kw): print('name:', name, 'age:', age, 'other:', kw)
-
函数
person除了必选参数name和age外,还接受关键字参数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'}
-
关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
-
命名关键字:
-
和关键字参数
**kw不同,命名关键字参数需要一个特殊分隔符*,*后面的参数被视为命名关键字参数。def person(name, age, *, city, job): print(name, age, city, job) >>> person('Jack', 24, city='Beijing', job='Engineer') Jack 24 Beijing Engineer -
命名关键字参数必须传入参数名,这和位置参数不同。如果没有传入参数名,调用将报错:
>>> person('Jack', 24, 'Beijing', 'Engineer') Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: person() takes 2 positional arguments but 4 were given
-
和关键字参数
-
组合参数
-
参数定义的顺序必须是:必选参数、默认参数、可变参数/命名关键字参数和关键字参数。
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) >>> 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} # 最神奇的是通过一个tuple和dict,你也可以调用上述函数: >>> args = (1, 2, 3, 4) >>> kw = {'d': 99, 'x': '#'} >>> f1(*args, **kw) a = 1 b = 2 c = 3 args = () kw = {'d': 99, 'x': '#'} >>> args = (1, 2, 3) >>> kw = {'d': 88, 'x': '#'} >>> f2(*args, **kw) a = 1 b = 2 c = 3 d = 88 kw = {'x': '#'}*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})。
- 可变参数既可以直接传入:
-
参数定义的顺序必须是:必选参数、默认参数、可变参数/命名关键字参数和关键字参数。
-
默认参数
-
切片
>>> L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack'] >>> L[0:3] ['Michael', 'Sarah', 'Tracy'] >>> L[:3] ['Michael', 'Sarah', 'Tracy'] >>> L = list(range(100)) >>> L [0, 1, 2, 3, ..., 99] #前10个数,每两个取一个: >>> L[:10:2] [0, 2, 4, 6, 8] # 只写[:]就可以原样复制一个list: >>> L[:] [0, 1, 2, 3, ..., 99] # 字符串'xxx'也可以看成是一种list,每个元素就是一个字符。因此,字符串也可以用切片操作,只是操作结果仍是字符串: >>> 'ABCDEFG'[:3] 'ABC' >>> 'ABCDEFG'[::2] 'ACEG' -
迭代
-
dict迭代
d = {'a': 1, 'b': 2, 'c': 3} # 按照key迭代 >>> for key in d: ... print(key) # 按照value迭代 for value in d.values() # 按照k-v迭代 for k, v in d.items() -
判断可迭代:通过collections模块的Iterable类型判断
>>> from collections import Iterable >>> isinstance('abc', Iterable) # str是否可迭代 True >>> isinstance([1,2,3], Iterable) # list是否可迭代 True >>> isinstance(123, Iterable) # 整数是否可迭代 False -
下标循环:Python内置的
enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身:>>> for i, value in enumerate(['A', 'B', 'C']): ... print(i, value) ... 0 A 1 B 2 C
-
dict迭代
-
列表生成式
>>> list(range(1, 11)) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> [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'] >>> import os # 导入os模块,模块的概念后面讲到 >>> [d for d in os.listdir('.')] # os.listdir可以列出文件和目录 ['.emacs.d', '.ssh', '.Trash', 'Adlm', 'Applications', 'Desktop', 'Documents', 'Downloads', 'Library', 'Movies', 'Music', 'Pictures', 'Public', 'VirtualBox VMs', 'Workspace', 'XCode'] >>> d = {'x': 'A', 'y': 'B', 'z': 'C' } >>> [k + '=' + v for k, v in d.items()] ['y=B', 'x=A', 'z=C'] -
生成器
>>> 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> # 创建L和g的区别仅在于最外层的[]和(),L是一个list,而g是一个generator。 #遍历 >>> g = (x * x for x in range(10)) >>> for n in g: ... print(n) #要把fib函数变成generator,只需要把print(b)改为yield b就可以了: def fib(max): n, a, b = 0, 0, 1 while n < max: yield b a, b = b, a + b n = n + 1 return 'done' >>> f = fib(6) >>> f <generator object fib at 0x104feaaa0> >>> for n in fib(6): ... print(n)




近期评论