python基础语法一些需要注意的地方(未完待续)
注:不适合没有编程基础的人
一些特有的数据类型
list:是一种有序的集合,可以随时添加和删除其中的元素。
[1,2,3]
tuple:也是有序列表,但是tuple一旦初始化就不能修改(里面有list元素,list里的值可变但list不能变)
(1,2,3,a,b)
dict:使用键-值(key-value)存储,具有极快的查找速度.其中key值不能变但value可变。(可用dict[key]索引)
['a':1,'b':2]
set:和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。(不能添加可变元素–变量)
[1,2,3]
一些特殊的语法
切片
L[0:3]表示,从索引0开始取,直到索引3为止,但不包括索引3。即索引0,1,2,正好是3个元素。
如果第一个索引是0,还可以省略:
Python支持L[-1]取倒数第一个元素,它同样支持倒数切片
循环及列表生成式
for x in …: 把每个元素代入变量x,然后执行缩进块的语句
sum = 0
for x in range(10):#一加到十
sum = sum + x
print(sum)
因为ict的存储不是按照list的方式顺序排列,所以,迭代出的结果顺序很可能不一样。
for key in dict:
Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身:
for i, value in enumerate(['A', 'B', 'C']):
print(i, value)
[x * x for x in range(1, 11)]
#[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
写列表生成式时,把要生成的元素x * x放到前面,后面跟for循环,就可以把list创建出来,十分有用,多写几次,很快就可以熟悉这种语法。
for循环后面还可以加上if判断,这样我们就可以筛选出仅偶数的平方:
[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']
for循环其实可以同时使用两个甚至多个变量,比如dict的items()可以同时迭代key和value
>>> for k, v in d.items():
... print(k, '=', v)
列表生成式也可以使用两个变量来生成list:
>>> d = {'x': 'A', 'y': 'B', 'z': 'C' }
>>> [k + '=' + v for k, v in d.items()]
#['y=B', 'x=A', 'z=C']
生成器
生成器:在循环的过程中不断推算出后续的元素,把一个列表生成式的[]改成(),就创建了一个generator,generator也是可迭代对象,可以用for直接循环
g = (x * x for x in range(10))
如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:
generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行
def odd():
print('step 1')
yield 1
print('step 2')
yield(3)
print('step 3')
yield(5)
>>> o = odd()
>>> next(o)
step 1
1
>>> next(o)
step 2
3
>>> next(o)
step 3
5
>>> next(o)
#报错信息
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
可
以看到,odd不是普通函数,而是generator,在执行过程中,遇到yield就中断,下次又继续执行。执行3次yield后,已经没有yield可以执行了,所以,第4次调用next(o)就报错
其他
pass语句什么都不做,那有什么用?实际上pass可以用来作为占位符,比如现在还没想好怎么写函数的代码,就可以先放一个pass,让代码能运行起来。
赋值语句
a, b = b, a + b
函数
高阶函数
函数名也是变量
map()函数接收两个参数,一个是函数,一个是Iterable
reduce把一个函数作用在一个序列[x1, x2, x3, …]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。
sorted()函数也是一个高阶函数,它还可以接收一个key函数来实现自定义的排序,例如按绝对值大小排序:
>>> sorted([36, 5, -12, 9, -21], key=abs)
[5, 9, -12, -21, 36]
函数的返回
高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。
返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
def xxx():
返回多个值的时候return x1,x2,x3 实质是返回一个tuple,在语法上,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值
匿名函数
匿名函数lambda x: x * x实际上就是:
def f(x):
return x * x
关键字lambda表示匿名函数,冒号前面的x表示函数参数
functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。
参数
Python函数在定义的时候,默认参数L的值就被计算出来了,即[],因为默认参数L也是一个变量,它指向对象[],每次调用该函数,如果改变了参数L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了。因此最好不要把默认参数定义成可变对象
可变参数
定义可变参数和定义一个list或tuple参数相比,仅仅在参数前面加了一个*号。在函数内部,参数numbers接收到的是一个tuple,因此,函数代码完全不变。但是,调用该函数时,可以传入任意个参数,包括0个参数:
可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。
nums = [1, 2, 3]
calc(*nums)
关键字参数
关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict
def person(name, age, **kw):
调用:
person('Bob', 35, city='Beijing')
#或
extra = {'city': 'Beijing', 'job': 'Engineer'}
person('Jack', 24, **extra)
**
extra表示把extra这个dict的所有key-value用关键字参数传入到函数的kw参数,kw将获得一个dict,注意kw获得的dict是extra的一份拷贝,对kw的改动不会影响到函数外的extra**
命名关键字参数
命名关键字参数需要一个特殊分隔符,后面的参数被视为命名关键字参数
命名关键字参数必须传入参数名,这和位置参数不同。如果没有传入参数名,调用将报错
命名关键字参数可以有缺省值,从而简化调用
使用命名关键字参数时,要特别注意,如果没有可变参数,就必须加一个*作为特殊分隔符。如果缺少,Python解释器将无法识别位置参数和命名关键字参数:
def person(name, age, *, city, job)
person('Jack', 24, city='Beijing', job='Engineer')
参数调用顺序
在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。
但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。