[关闭]
@lgh-dev 2018-01-13T08:35:21.000000Z 字数 4955 阅读 692

python基础

python

数据类型





变量

这种变量本身类型不固定的语言称之为动态语言,与之对应的是静态语言。静态语言在定义变量时必须指定变量类型,如果赋值的时候类型不匹配,就会报错

常量

所谓常量就是不能变的变量
python中有两种除法,/除法结果是浮点数,即使整除
//成为地板除,整数的地板除//永远是整数,即使除不尽

字符串和编码


函数

python 常见的一些内置函数: https://docs.python.org/3/library/functions.html

函数名其实就是指向一个函数对象的引用,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”

如果想定义一个什么事也不做的空函数,可以用pass语句;

调用函数时,如果参数个数不对,Python解释器会自动检查出来,并抛出TypeError;

Python的函数返回多值其实就是返回一个tuple,但写起来更方便,在语法上,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值

函数参数

  1. def add_end(L = [] ):
  2. L.append('END')
  3. return L
  4. 可以改为如下:
  5. def add_end(L=None):
  6. if L is None:
  7. L = []
  8. L.append('END')
  9. return L

因为不变对象一旦创建,对象内部的数据就不能修改,这样就减少了由于修改数据导致的错误。此外,由于对象不变,多任务环境下同时读取对象不需要加锁,同时读一点问题都没有。我们在编写程序时,如果可以设计一个不变对象,那就尽量设计成不变对象。

Python允许你在list或tuple前面加一个*号,把list或tuple的元素变成可变参数传进去

可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict

和关键字参数**kw不同,命名关键字参数需要一个特殊分隔符后面的参数被视为命名关键字参数

使用命名关键字参数时,要特别注意,如果没有可变参数,就必须加一个作为特殊分隔符。
如果缺少
,Python解释器将无法识别位置参数和命名关键字参数

函数组合参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数

递归函数

尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况

使用递归函数的优点是逻辑简单清晰,缺点是过深的调用会导致栈溢出。

切片

L[0:3]表示,从索引0开始取,直到索引3为止,但不包括索引3。即索引0,1,2,正好是3个元素;
如果第一个索引是0,还可以省略

字符串'xxx'也可以看成是一种list,每个元素就是一个字符。因此,字符串也可以用切片操作,只是操作结果仍是字符串

迭代

当我们使用for循环时,只要作用于一个可迭代对象,for循环就可以正常运行,而我们不太关心该对象究竟是list还是其他数据类型
那么,如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断

  1. >>> from collections import Iterable
  2. >>> isinstance('abc', Iterable)
  3. True
  4. >>> isinstance([1,2,3], Iterable)
  5. True
  6. >>> isinstance(1, Iterable)
  7. False

Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身

列表生成式

而列表生成式则可以用一行语句代替循环生成上面的list

  1. >>> [x * x for x in range(1, 11)]
  2. [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

for循环后面还可以加上if判断,这样我们就可以筛选出仅偶数的平方:

  1. >>> [x * x for x in range(1, 11) if x % 2 == 0]
  2. [4, 16, 36, 64, 100]

还可以使用两层循环,可以生成全排列:

  1. >>> [m + n for m in 'ABC' for n in 'XYZ']
  2. ['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']

for循环其实可以同时使用两个甚至多个变量,比如dict的items()可以同时迭代key和value
因此,列表生成式也可以使用两个变量来生成list

  1. >>> d = {'x': 'A', 'y': 'B', 'z': 'C' }
  2. >>> [k + '=' + v for k, v in d.items()]
  3. ['y=B', 'x=A', 'z=C']
生成器

通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了

在Python中,这种一边循环一边计算的机制,称为生成器:generator

如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator

最难理解的就是generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行

  1. def odd():
  2. print('step 1')
  3. yield 1
  4. print('step 2')
  5. yield(3)
  6. print('step 3')
  7. yield(5)
  8. >>> o = odd()
  9. >>> next(o)
  10. step 1
  11. 1
  12. >>> next(o)
  13. step 2
  14. 3
  15. >>> next(o)
  16. step 3
  17. 5
  18. >>> next(o)
  19. Traceback (most recent call last):
  20. File "<stdin>", line 1, in <module>
  21. StopIteration

用for循环调用generator时,发现拿不到generator的return语句的返回值。如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中
generator的工作原理,它是在for循环的过程中不断计算出下一个元素,并在适当的条件结束for循环。对于函数改成的generator来说,遇到return语句或者执行到函数体最后一行语句,就是结束generator的指令,for循环随之结束

迭代器

直接作用于for循环的数据类型有以下几种:
一类是集合数据类型,如list、tuple、dict、set、str等;
一类是generator,包括生成器和带yield的generator function
这些可以直接作用于for循环的的对象统称为可迭代对象: Iterable
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator

生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。
把list、dict、str等Iterable变成Iterator可以使用iter()函数;

Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注