欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

python学习笔记(三)

程序员文章站 2022-09-27 09:18:21
一、高级特性 1、切片 取list或tuple中的一部分元素,可使用切片操作符(:)。 L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack'] #取前三个元素 >>>L[0:3] ['Michael', 'Sarah', 'Tracy'] #索引号第1个是0 ......

一、高级特性

1、切片

取list或tuple中的一部分元素,可使用切片操作符(:)。

l = ['michael', 'sarah', 'tracy', 'bob', 'jack']

#取前三个元素
>>>l[0:3]
['michael', 'sarah', 'tracy']
#索引号第1个是0,可省略
>>>l[:3]
['michael', 'sarah', 'tracy']

#取第1-3个字元素
>>>l[1:4]
['sarah', 'tracy', 'bob']

也可以倒数取:

l = list(range(100))
>>> l
[0, 1, 2, 3, ..., 99]

#取最后10个数
>>>l[-10:]
[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
#取倒数第二个数
>>>l[-2,-1]
[98]

也可以每n个取出元素:

>>> l[:10:2]  #前10个数,每两个取一个
[0, 2, 4, 6, 8]
>>> l[::5] #所有数,每5个取一个
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]

 

 2、迭代

可用for循环遍历集合对象中所有元素的行为,称为迭代(iteration)。

可迭代的对象:list、tuple、dict、set、字符串等。 

d = {'a': 1, 'b': 2, 'c': 3}
for key in d:       #dict默认只迭代key值
    print (key)

for value in d.values()  #迭代value值
    print (value)

for k,v in d.items() #迭代key和value值
    print (k, v)           

 

 

需要将list实现迭代时出现索引下标,可用enumerate函数:

for i, value in enumerate(['a', 'b', 'c']):
    print(i, value)

 

 

判断一个对象是否可迭代,可用collections模块的iterable类型判断:

>>>from collections import iterable
>>>isinstance('abc', iterable)  #判断字符串是否可迭代
true

>>>isinstance(123, iterable)  #判断整数是否可迭代
false

 

 

3、列表生成式

list(range(1,11))可以生成[1,2,3,....10]的list。

但如果要生成[1*1, 2*2, 3*3, ..., 10 * 10]这样的列表,除了用循环算法,还可以用列表生成式:[x * x for x in range(1,10)]

列表生成式的格式:[表达式 for x in range()]

 

for循环后加上if判断,可筛选for循环的结果:

>>> [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']

 

 

使用两个变量来生成list:

>>> d = {'x': 'a', 'y': 'b', 'z': 'c' }
>>> [k + '=' + v for k, v in d.items()]
['y=b', 'x=a', 'z=c']

 

 

if...else可以用在表达式当中:

[x if x % 2 == 0 else -x for x in range(1, 11)]
[-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]

 

上面的表达式,相当 ?:三目运算符:x= x % 2 ?: -x。python貌似没有三目运算符,这里仅供理解用。
 
4、生成器generator
如果使用列表生成式,比如:
>>> l = [x * x for x in range(10)]
>>> l
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

 则list会直接生成出来。但是如果生成十万百万个这样的元素,则会消耗掉内存,可使用生成器来代替上面的列表生成式:

>>> g = (x * x for x in range(10))

 

将列表生成式两边的[]括号改成()括号即可创建了一个generator。
也可以写成函数的方法:
def g():
    for x in range(10):
        yield x*x
    return 'end'

 函数体内包含yield则此函数为generator。

 

要调用该generator时,首先要生成一个generator对象,然后再用next()函数不断获得下一个yield的返回值。

o = g()

while true:
    try:
        x = next(o)
        print('g:', x)
    except stopiteration as e:   #使用stopiteration捕获return值
        print('generator return value:', e.value)
        break

 

 

也可以用for循环来不断获得返回值,这时不需要next()函数,也不会产生stopintertaion错误。

for n in g():
    print(n)

 

 

5、迭代器

可以for循环的数据类型有两种:

一种是集合类型,归属于interable对象,比如:list、tuple、dict、set、str等;

一种是generator生成器,这类归属于iterator对象。

listdictstriterable变成iterator可以使用iter()函数:

>>> isinstance(iter([]), iterator)
true
>>> isinstance(iter('abc'), iterator)
true

 

二、函数式编程

函数式编程的重要特点:函数本身可以作为参数传入到另一个函数,还允许返回一个函数。

python对函数式编程提供部分支持。

(一)函数作为参数传入:

1、map和reduce函数

map():接收两个参数,一个是函数(此函数只有一个参数),一个是iterable,作用是将传入的函数作用到传入序列的每一个元素上。

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]

 

reduce():把一个函数作用在一个序列上,该函数必须有两个参数,接收序列中前两个的累积结果和下一个元素。效果如下:

reduce(f, [x1,x2,x3,x4]) = f(f(f(x1,x2), x3), x4)

from functools import reduce
def add(x, y):
     return x + y

reduce(add, [1, 3, 5, 7, 9])

#序列累积求和:25

 

2、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]

 

 

3、sorted排序函数

sorted()函数有三个参数,第一参数是要接受排序的序列,第二参数可选,用于在排序前对序列作用于每个元素,第三参数可选,默认为false,设为true则表示反向排序。

sorted(['bob', 'about', 'zoo', 'credit'])
#按ascii码排序: ['credit', 'zoo', 'about', 'bob']

sorted(['bob', 'about', 'zoo', 'credit'], key=str.lower)
#对每个元素变小写,再按ascii码排序:['about', 'bob', 'credit', 'zoo']

sorted(['bob', 'about', 'zoo', 'credit'], key=str.lower, reverse=true)
#每个元素变小写,再按ascii码反向排序:['zoo', 'credit', 'bob', 'about']

 

 

(二)函数作为返回值:


函数可作为返回值返回,此时返回的函数体并不会立即执行。

#返回求和函数
def lazy_sum(*args):
    def sum():
        ax = 0
        for n in args:
            ax = ax + n
        return ax
    return sum

f = lazy_sum(1, 3, 5, 7, 9)
#调用函数f时,才会计算求和结果
f()
#结果:25

 

注意:返回的函数体不要引用局部会变化的变量,否则会引起预想不到的结果。

 

(三)匿名函数

py的匿名函数写法:

lambda <参数>:返回函数体结果。

 

匿名函数的限制:只有有一个表达式,不用写return,返回值就是该表达式的结果。

f = lambda x:x*x

#实际上就是:
def f(x):
    return x*x

 

 

(四)装饰器decorator

当需要增强函数功能时,可使用装饰器decorator。

比如,在调用now()函数前显示自动打印函数日志。

def log(func):
    def wrapper(*args, **kw):
        print('调用 %s():' % func.__name__)
        return func(*args, **kw)
    return wrapper

#要使用上面的封装器,则可这样使用:
@log
def now():
     print('2020-04-14')


#调用now()
now()
#显示:
#call now():
#2020-04-14

 

 

(五)偏函数partial function

偏函数的作用:把一个函数的某些函数用某个值固定,并返回一个新函数,可以简单调用。

举例:

int()函数可把字符串转换为整数,传入字符串时,会默认按十进制转换。此函数的第二个参数为默认值 10,可以用偏函数固定成其他值:

import functools
int2 = functools.partial(int, base=2)
int2('1000000')
#结果:64

 

 

三、模块

模块作用:将代码利用模块分隔开,利于维护;

python:一个.py文件为一个模板,一个文件夹为一个package(文件夹下必须包含__init__.py)。

模块名起名规范:遵循py变量命名规范,不要使用中文和特殊字符,不要与系统模块名冲突;

示例:

mycompany
 ├─ web
 │  ├─ __init__.py
 │  ├─ utils.py
 │  └─ www.py
 ├─ __init__.py
 ├─ abc.py
 └─ utils.py

文件www.py的模板名为:mycompany.web.www。utils.py模块名分别有:mycompany.web.utils和mycompany.utils。

 

引用模块:

import 模块名

python在指定的路径下搜索对应的.py文件来加载模块。包括:当前目录、所有已安装的内置模块和第三模块目录。这些目录存放在sys模块下的path变量中。

>>> import sys
>>> sys.path
['', '/library/frameworks/python.framework/versions/3.6/lib/python36.zip', '/library/frameworks/python.framework/versions/3.6/lib/python3.6', ..., '/library/frameworks/python.framework/versions/3.6/lib/python3.6/site-packages']

 

 

添加模块搜索目录的方法:

(1)运行时添加:

>>> import sys
>>> sys.path.append('/users/michael/my_py_scripts')

 

这种方法在运行时添加,运行完后失效。

(2)设置pythonpath环境变量

这种方式与path环境变量类似。

 

模块文件的编写规范:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

' a test module '

__author__ = 'michael liao'

import sys

def test():
    args = sys.argv
    if len(args)==1:
        print('hello, world!')
    elif len(args)==2:
        print('hello, %s!' % args[1])
    else:
        print('too many arguments!')

if __name__=='__main__':
    test()

 

前两行为标准注释;

第4行是一个模块的文档注释,任何模块代码第一个字符串都被视为模块的文档注释;

第6行__author__变量是作者名。

而后的代码就是真正的代码部分。

最后两行,__name__变量是特殊变量,当模块在命令行模式运行时此变量为__main__字符串,常用于运行测试。

另外说明一点:

模块中的函数和变量都是公开的,无公有或私有化一说。只是我们自己可以规定_或__开头的应该业内口头规定为私有变量或函数,但实际上仍可以被外部调用。

 

安装第三方模块:

在安装了python后,可以使用pip(3版本为pip3)命令安装第三方库。

第三方库一般都在 中注册。

安装常用模块,可以使用anaconda更方便。下载地址:https://www.anaconda.com/download/

有关介绍说明: