cookbook(小结1)

数据结构和算法

序列分解为单独的变量

任何序列(或可迭代对象)都可以通过一个简单的赋值操作来分解为单独的变量,唯一的要求是变量的总数和结构要与序列相吻合。

不仅仅只是元组或列表,只要对象恰好是可迭代的,那么就可以执行分解操作,这包括字符串、文件、迭代器以及生成器。

通常用一个用不到的变量名(_)来作为要丢弃的值的名称。

从任意长度的可迭代对象中分解元素

‘*表达式’,‘*_’丢弃多个值。

保存最后N个元素

collections.deque(max=N)创建一个固定长度的队列,当有新纪录加入而队列已满时会自动移除最老的那条纪录。

找出最大或最小的N个元素

heapq.nlargest(n, list),heapq.nsmallest(n, list)

在字典中将键映射到多个值上

用collections.defaultdict。

让字典保持有序

使用collections模块中的OrderedDict()类。当对字典做迭代时,它会严格按照元素初始添加的顺序进行。

与字典有关的计算

通常利用zip()将字典的键和值反转过来。

在两个字典中寻找相同点

通过key()或者items()方法执行常见的集合操作。

从序列中移除重复项且保持元素间顺序不变

如果序列中的值时可哈希的,可以通过集合和生成器解决,否则使用key来排除。

对切片命名

内置的slice()函数会创建一个切片对象,可以用在任何允许进行切片操作的地方,还可以用过slice().star,slice().stop,slice().step属性来得到该对象的信息。

找出序列中出现次数最多的元素

可以使用collections模块中的Counter()类,Counter对象可以同各种数学运算操作结合起来使用。

通过公共键对字典列表排序

利用operator模块中的itemgetter函数对这类结构进行排序。

var = sorted(row, key=itemgetter(key,key,…))

根据字段将记录分组

使用itertools.groupby()函数对数据进行分组,groupby()通过扫描序列找出拥有相同值(或由参数key指定的函数返回的值)的序列项,并将它们分组,groupby()创建了一个迭代器,而在每次迭代时都会返回一个值(value)和一个子迭代器(sub_iterator),这个子迭代器可以产生所有在该分组内具有该值的项。

筛选序列中的元素

可以使用生成器表达式通过迭代的方式产生筛选的结果,itertools.compress()可以接受一个可迭代对象以及一个布尔选择器序列作为输入,输出时,它会给出所有在相应的布尔选择器中为True的可迭代对象元素。

将名称映射到序列的元素中

使用collections.namedtuple(),如果要修改任何属性,可以通过namedtuple实例的_replace()方法来实现。

将多个映射合并为单个映射

利用collections模块中的ChainMap类来解决,如果具有重复的键,会采用第一个映射中所对应的值。

 

字符串和文本

针对任意多的分隔符拆分字符串

使用re.split()

在字符串的开头或结尾处做文本匹配

如果需要同时针对多个选项做检查,只需给startswith()和endswith()提供包含可能选项的元组即可。

利用Shell通配符做字符串匹配

使用fnmatch.fnmatch(name, 匹配格式)和fnmatchcase(name, 格式)。

文本模式的匹配和查找

   使用str.find()、str.endswith()、str.startswith()和re.find()等函数。

查找和替换文本

   使用str.replace(),re.sub(模式,替换的模式),除了得到替换后的文本,如果还想知道一共完成了多少次替换,可以使用re.subn()。

以不区分大小写的方式对文本做查找和替换

   使用re模块并且对各种操作都要加上re.IGNORECASE标记。

定义实现最短匹配的正则表达式

   在模式中的*操作符后加上?修饰符。

编写多行模式的正则表达式

   函数re.compile()可接受re.DOTALL标记使得正则表达式中的句点(.)可以匹配所有的字符,也包括换行符。

将Unicode文本统一表示为规范形式

   使用unicodedata.normalize(),第一个参数指定了字符串应该如何完成规范表示,NFC表示字符是全组成的,NFD表示应该使用组合字符,每个字符应该是能完全分开的,使unicodedata.combining()函数判断它是否为一个组合字符。

从字符串中去掉不需要的字符

   字符的strip()、lstrip()、rstrip()、replace()方法。

以固定的列数重新格式化文本

   使用textwrap模块,textwrap.fill(text, n, 限定符),限定符:initial_indent=’’(开头),subsequent_indent=’’(结尾),终端的尺寸可以通过os.get_terminal_size()来获取。

在文本中处理HTML和XML实体

使用html.escape()函数来完成替换<or>这样的特殊字符。

如果要生成ASCII文本,并且向针对非ASCII字符将它们对应的字符编码实体嵌入到文本中,可以在各种同I/O相关的函数中使用errors=’xmlcharrefreplace’参数来实现。

文本分词

形如?P<TOKENNAME>这样的约定是用来将名称分配给该模式的。

编写一个简单的递归下降解析器

在字节串上执行文本操作

字符串已经支持大多数和文本字符串一样的内建操作,类似这样的操作在字节数组上也能完成,

  可以在字节串上执行正则表达式的模式匹配操作,但是模式本身需要以字节串的形式来指定,字节串上没有普通字符的那种格式化操作。

数字、日期和时间

对数值进行取整

对于简单的取整操作,使用内建的round(value, ndigits)函数,取整操作会取到离该值最接近的那个偶数上。传递给round()的参数ndigits可以是负数,在这种情况下会相应地取整到十位、百位、千位等。

执行精确的小数计算

使用decimal.Decimal(),创建一个本地的上下文环境来设置其精度:

from decimal import localcontext

with localcontext() as ctx:   ctx.prex = n (n为小数点后精度)

对数值做格式化输出

同二进制、八进制和十六进制数打交道

要将一个整数转换为二进制、八进制或十六进制的文本字符串形式,使用bin()、oct()、hex(),如果不希望出现0b、0o、0x这样的前缀,可以使用format()函数。要将字符串形式的整数转换为不同的进制,只需要使用int()函数再配合适的进制即可。

从字节串中打包和解包大整数

要将字节解释为整数,可以使用int.from_bytes(字节,字节序),,要将一个大整数重新转换为字节串,可以使用int.to_bytes(字节数,字节序),字节序:big ,little。

如果尝试将一个整数打包成字节串,但字节大小不合适的话就会得到一个错误的信息,可以使用int.bit_length()方法来确定需要用到多少位才能保存这个值。

复数运算

复数可以通过complex(real, imang)函数来指定,或者通过浮点数再加上后缀j来指定,实部、虚部、共轭值可以属性.real, .imag, .conjugate()来提取。

如果要执行有关复数的函数操作,使用cmath.sin(), cmath.cos(), cmath.exp().

处理无穷大和NaN

通过float()来创建,float(‘inf’),float(‘-inf’),

float(‘nan’),要检测是否出现了这些值,可以使用math.isinf()和math.isnan()函数。无穷大值在数字计算中会进行传播,NaN会通过所有的操作进行传播,且不会引发任何异常。

分数的计

使用fractions.Fraction(分子,分母),var.numerator, bar.denominator得到分子、分母。

处理大型数组的计算

矩阵和线性代数的计算

使用Numpy.matrix()。

随机选择

要从序列中随机挑选元素,使用random.choice(values)。

如果想取样出N个元素,将选出的元素移除以做进一步的考察,使用random.sample(values, n).

如果只是想在序列中原地打乱元素的顺序,可以使用random.shuffle()。

要产生随机整数,使用random.randint(star, end)。

要产生0到1之间均匀分布的浮点数值,使用random.random()。

时间换算

使用datetime模块来完成不同时间单位的换算,要表示时间间隔,创建一个timedelta实例, 或者使用dateutil.relativedelta()函数。

计算上周五的日期

找出当月的日期范围

将字符转换为日期

使用datetime.strptime(str, 格式化代码)。

处理涉及到时区的日期问题

使用pytz模块。

迭代器和生成器

手动访问迭代器中的元素

委托迭代

用生成器创建新的迭代模式

实现迭代协议

反向迭代

使用内建的revered()函数,反向迭代只有在待处理的对象有可确定的大小,或者对象实现了__reversed__()特殊方法时,才能奏效,如果这两个条件都无法满足,则必须首先将这个对象转换为列表。

定义带有额外状态的生成器函数

对迭代器做切片处理

使用itertools.islice(literable, start, stop[,step])函数.

跳过可迭代对象中的前一部分元素

使用itertools.dropwhile(函数,可迭代对象),只有序列中的前面几个元素在函数中返回True即可。

迭代所有可能的组合或排列

使用itertools.permutations(items,长度)返回items所有可能情况。

使用itertools.combinations(items,长度)产生序列中元素的全部组合,顺序不予考虑。Itertools.combinations_with_replacement(items,长度)运行元素重复选择。

以索引-值对的形式迭代序列

使用enumerate()函数

同时迭代多个序列

使用zip()函数

在不同容器中进行迭代

使用itertools.chain(iterbales, iterables)连续访问并返回每个可迭代元素中的元素。

创建处理数据的管道

扁平化处理嵌套型的序列

合并多个有序序列,再对整个有序序列进行迭代

使用heaq.merge()函数,依次迭代最小元素。

用迭代器取代while循环

文件和I/O

读写文本文件

将输出重定向到文件中

以不同的分隔符或结尾符完成打印

读写二进制数据

对已不存在的文件执行写入操作

    使用open()函数的X模式代替常见的w模式,如果文件是二进制,那么用xb模式代替xt。

在字符串上执行I/O操作

使用io.StringIO()和io.BytesIO()类来创建类似文件的对象。

读写压缩的数据文件

使用模块gzip和bz2。

对固定大小的记录进行迭代

使用iter()和functools.partial()。

将二进制数据读取到可变缓冲区中

要将数据读取到可变数组中,使用文件对象的readinto()方法

对二进制文件做内存映射

处理路径名

使用os.path模块中的函数。

检测文件是否存在

获取目录内容的列表

使用os.listdir()函数。

绕过文件名编码

打印无法解码的文件名

为已经打开的文件添加或修改编码方式

如果想为一个以二进制模式打开的文件对象添加Unicode编码/解码,可以用io.TextIOWrapper()对象将其包装。

如果想修改一个已经以文本模式打开的文件的编码,可以在用新的编码替换之前的编码前,用detach()方法将已有的文件编码层移除。

将字节数据写入文本文件

将已有的文件描述符包装为文件对象

创建临时文件和目录

模块tempfile模块中有各种函数可以来完成这个任务,要创建一个未命名的临时文件,可以使用tempfile.TempoaryFile(模式,encoding=’’,),要创建一个临时目录,可以使用tempfile.TemporaryDirectory()。

同串口进行通信

序列化Python对象

使用pickle模块。

数据编码与处理

读写CSV数据

使用csv模块

读写JSON数据

使用json.dumps()将Python数据结构转换为JSON,json.loads()将JSON编码的字符串再转换回Python数据结构。

解析简单的XML文档

使用xml.etree.ElementTree模块从简单的XML文档中提取出数据,xml.etree.ElementTree.parse()函数将整个XML文档解析为下一个文档对象,之后,就可以利用find()、iterfind()、findtext()方法查询特定的XML元素。

以增量方式解析大型XML文件

from xml.etree.ElementTree import iterparse

将字典转换为XML

from xml.etree.ElementTree import Element, tostring

解析、修改和重写XML

from xml.etree.ElementTree import Element, parse

用命名空间来解析XML文档

同关系型数据库进行交互

编码和解码十六进制数字

如果需要编码或解码由十六进制数组成的原始字符串,可以使用binascii.b2a_hex()、binascii.a2b_hex(),也可以使用base64.b16encode()、base64.b16decode(),base64只能对大写形式的十六进制数进行操作,而binascii模块能够处理任意一种情况。

读写二进制结构的数组

使用struct模块

读取嵌套型和大小可变的二进制结构

数据汇总和统计

函数

编写可接受任意数量参数的函数

使用*开头的参数可接受任意数量的位置参数的函数

使用**开头的参数可接受任意数量的关键字参数

以*打头的参数只能作为最后一个位置参数出现,而以**打头的参数只能最为最后一个参数出现。

编写只接受关键参数的函数

将关键字参数放置在以*打头的参数或者是一个单独的*之后。

将元数据信息附加到函数参数上

函数注解只会保存在函数的__annotions__属性中。

从函数中返回对个值

定义带有默认参数的函数

如果默认值是可变容器的话,比如说列表、集合或者字典,那么应该把None作为默认值,如果不打算提供一个值,只是想编写代码来检测可选参数是否被赋予了某个特定的值,可以使用object()作为默认值。

默认值已经在函数定义的时候就确定好了,给默认参数赋值的总应该是不可变的对象,比如None、True、False、数字或者字符串。

定义匿名或内联函数(lambda)

在匿名函数中绑定变量的值

如果希望匿名函数可以在定义的时候绑定变量,并且保持不变,那么可以将那个值作为默认参数实现:lambda x, y=y: x + y

让带有N个参数的可调用对象以较少的参数形式调用

如果需要减少函数的参数数量,应该使用functools.partial()。函数partial()允许我们给一个或多个参数指定固定的值,以此减少需要提供之后调用的参数数量。

用函数代替只有单个方法的类

在回调函数中携带额外的状态

内联回调函数

访问定义在闭包内的变量

 

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/GongShiShen/article/details/82869008