当前位置:   article > 正文

Python高级编程技巧实战_python 高级例程

python 高级例程

在这里插入图片描述

1. 数据结构

1.1 在列表、字典、集合中根据条件筛选数据

在这里插入图片描述
元组list就是数组,没有元组tuple (不允许修改的数组!),集合set不重复的数组,字典dict就是C++的map。

1.1.1 列表list筛选

filter筛选filter(lambda匿名函数, list)

from random import randint
data = [randint(-10, 10) for _ in range(10)]
print(data)
data = filter(lambda x: x > 0, data)
print(list(data))
  • 1
  • 2
  • 3
  • 4
  • 5

列表解析[x for x in list 条件]

data = [randint(-10, 10) for _ in range(10)]
print(data)
data = [x for x in data if x > 0]
print(list(data))
  • 1
  • 2
  • 3
  • 4

1.1.2 字典dict筛选

列表解析[k:v for k,v in dict.items() 条件],注意for x in dict只能迭代keys,而dict.items()可以同时迭代出k和v。

from random import randint
data = {x:randint(1,100) for x in range(20)}
print(dict)
data = {k: v for k,v in data.items() if v > 60}
print(data)
  • 1
  • 2
  • 3
  • 4
  • 5

1.1.2 集合set筛选

列表解析{x for x in list 条件}

from random import randint
data = {randint(-10, 10) for _ in range(10)}
print(dict)
data = {x for x in data if x > 0}
print(data)
  • 1
  • 2
  • 3
  • 4
  • 5

1.2 lambda 表达式

匿名函数,常用来表示内部仅包含 1 行表达式的函数。

# 定义lambda函数,函数名funname
funname = lambda 形参列表 : 输出表达式
# 调用lambda函数
funname(实参列表)
  • 1
  • 2
  • 3
  • 4

其中,定义 lambda 表达式,必须使用 lambda 关键字;形参列表 等同于定义函数是指定的参数列表;value 为该表达式的名称。
如a+b函数

add = lambda a,b : a+b
add(1,1) # 2
  • 1
  • 2

1.3 map() 函数映射可迭代对象

map() 会根据提供的函数对指定序列做映射。
第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表。

map(function, iterable, ...)
list(map(function, iterable, ...))  # 使用 list() 将可迭代对象返回值转换为列表
  • 1
  • 2

1.4 对象.函数()直接修改,而不是 对象=对象.函数()重新赋值

这样的函数有append, clear, insert, sort, reverse, remove, extend

1.5 enumerate遍历列表元素

遍历列表元素,且要用到其位置索引index进行相应数据操作,使用Python的内置枚举函数enumerate()

data = [1, 4, 5, 7, 9]
for idx, num in enumerate(data):
    if num % 2:
        data[idx] = 0
print(data)

>>> [0, 4, 0, 0, 0]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

1.6 保存python对象

可以使用pickle保存pickle.dump(obj, file)和加载pickle.load(file) 任意python对象,包括自定义类在内的各种数据(包括numpy和tensor),比较适合Python本身复杂数据的存贮(写入二进制文件):

import pickle
d = {'a': 1, 'b': 2, 'c': 3}
with open('data.pkl', 'wb') as f:
    pickle.dump(d, f)

with open('data.pkl', 'rb') as f:
    d = pickle.load(f)
    print(d)
>>> {'a': 1, 'b': 2, 'c': 3}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

1.7 对可迭代对象进行排序(列表、元组、字典)

直接使用内置函数sorted

data = [-1, -10, 0, 9, 5]
new_data = sorted(data)  # 降序,可以将参数reverse设置为True
print(new_data)
>>> [-10, -1, 0, 5, 9]
  • 1
  • 2
  • 3
  • 4

适用于列表和元组,但注意此时输出类型变成了列表

data = (-1, -10, 0, 9, 5)
new_data = sorted(data, reverse=True)
print(new_data)
>>> [9, 5, 0, -1, -10]
  • 1
  • 2
  • 3
  • 4

对复杂的可迭代对象进行排序,比如列表中的元素为字典类型,在这个例子中,需要按age大小对列表进行排序,那么可以在参数key这使用匿名函数lambda,指定按参数key指定的关键字进行排序

data = [
    {"name" : "jia", "age" : 18},
    {"name" : "yi", "age" : 60},
    {"name" : "bing", "age" : 20}
]
new_data = sorted(data, key=lambda x: x["age"])
print(new_data)
>>> [{'name': 'jia', 'age': 18}, {'name': 'bing', 'age': 20}, {'name': 'yi', 'age': 60}]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

1.8 list去重,最简单的做法是将我们的list转为set

包含多个值的列表,但存在重复值,如果需要去重,最简单的做法是将我们的list转为set,会自动进行重复值的删除,但会打乱list的顺序!(将list2中的元素再按照list1中元素出现的顺序index重新排序,即可不改变原来元素顺序)

from random import randint
data = [randint(-10, 10) for _ in range(10)]
new_data = list(set(data))  # 被set打乱顺序的去重后的list
print(new_data)
new_data = sorted(new_data, key=data.index)  # 恢复原顺序的list
print(new_data)
>>> [1, 3, 4, 7, 9, 10, -5, -2]
>>> [3, 4, -5, 9, -2, 1, 7, 10]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

维护字典输入顺序: colections.OrderedDict代替内置dict字典,依次存入数据即可。

1.9 在字符串str中插入格式化对象

f-Strings将会是一个不错的方式

i = 9
data = f"res={i} * {i} = {i * i}"
print(data)

>>> res=9 * 9 = 81
  • 1
  • 2
  • 3
  • 4
  • 5

1.10 字符串列表拼接大字符串加速

定义一个列表,里面存放字符串对象,如果想实现拼接,由于字符串是不可变对象,定义空字符串进行遍历+拼接,对于大型字符串可能会导致特别慢,更优的方案是使用join,join前引号中的内容将作为分隔符

data = ["Hi", "my", "data"]
newdata = ''
for i in data:
    newdata += i + " "
print(newdata)

>>> Hi my data

data = ["Hi", "my", "data"]
newdata = " ".join(data)
print(newdata)

>>> Hi my data

data = ["Hi", "my", "data"]
newdata = ",".join(data)
print(newdata)

>>> Hi,my,data

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

1.11 合并两个字典

无需遍历对比判断键,只需使用如下语法前置**即可达到目的

data_1 = {"name" : "sds", "age" : "18"}
data_2 = {"name" : "sds", "uid" : "6688"}
out_data = {**data_1, **data_2}
print(out_data)

>>> {'name': 'sds', 'age': '18', 'uid': '6688'}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2. 迭代器与生成器

2.1 可迭代对象和迭代器对象

可迭代对象:列表、元组、字典、集合等。
迭代器对象:iter(可迭代对象)for循环in可迭代对象的原理就是不断调用迭代器对象的.__next__()方法

 l = [1, 2, 3, 4, 5]  # l是可迭代对象
for i in l:
    # i是迭代器对象,即不断调用iter(l).__next__()
    print(i)
  • 1
  • 2
  • 3
  • 4

2.2 生成器函数和生成器表达式

生成器函数:函数如果包含 yield 指令,该函数调用的返回值是一个生成器对象,此时函数体中的代码并不会执行,只有显示或隐示地调用.__next__()的时候才会真正执行里面的代码。yield可以暂停一个函数并返回此时的中间结果。该函数将保存执行环境并在下一次恢复。

def fun():
    print("in fun(), 1")
    yield 1

    print("in fun(), 2")
    yield 2

    print("in fun(), 3")
    yield 3

g = fun()  # 创建生成器对象(包含yeild的函数对象)

# 每次调用生成器对象的.__next__()方法就继续执行生成器函数到写一个yeild
print(g.__next__())
>>> in fun(), 1
>>> 1
print(g.__next__())
>>> in fun(), 2
>>> 2
print(g.__next__())
>>> in fun(), 3
>>> 3
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

生成器表达式:是用圆括号()来创建生成器,其语法与推导式相同,只是将 [] 换成了 () 。 生成器表达式会产生一个新的生成器对象。这种生成器表达式被成为隐式生成器,他是禁止使用 yield 和 yield from 表达式。

type([i for i in range(5)])
>>> list

type((i for i in range(5)))
>>> generator
  • 1
  • 2
  • 3
  • 4
  • 5

for调用迭代器和生成器的效果完全相同,但内部机理不同:

  • 迭代器是一种实现了迭代器协议的对象,通过 iter() 和 next() 来遍历可迭代对象。
  • 生成器是一种特殊的迭代器,使用 yield 语句暂停函数执行并return返回值,可以使用 for 循环来遍历。
a = (i for i in range(5))
for i in a:
    print(i)
    
>>> 0
>>> 1
>>> 2
>>> 3
>>> 4
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

2.3 一个for迭代多个可迭代对象

并行解析:for循环使用zip(多个可迭代对象),每次解析出1组各个可迭代对象中对应index的元素。

lst = [1, 2, 3, 4, 5]
string = ['a', 'b', 'c', 'd', 'e']
for l, s in zip(lst, string):
    print(l, s)

>>> 1 a
>>> 2 b
>>> 3 c
>>> 4 d
>>> 5 e
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

串行解析:from itertools import chain中的chain(多个可迭代对象),依次串行顺序解析出每个元素。

from itertools import chain
lst1 = [1, 2, 3, 4, 5]
lst2 = [6, 7, 8, 9, 10]
lst3 = [11, 12, 13, 14, 15]
for l in chain(lst1, lst2, lst3):
    print(l)
'''
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
'''
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

3. 字符串处理

3.1 拆分字符串

字符串调用split("分隔符"),每次仅实现单一分隔符的分割。

s = 'tiny-Kinetics-400\\abseiling\\_EDt9CNqqxk_000260_000270.mp4'
print(s.split('\\'))
>>> ['tiny-Kinetics-400', 'abseiling', '_EDt9CNqqxk_000260_000270.mp4']
  • 1
  • 2
  • 3

调用re.split('[多种分隔符]', s),实现多种分隔符的同时分割

import re
s = 'tiny-Kinetics-400\\abseiling\\_EDt9CNqqxk_000260_000270.mp4'
print(re.split('[\\\\/_.]', s))
>>> ['tiny-Kinetics-400', 'abseiling', '', 'EDt9CNqqxk', '000260', '000270', 'mp4']
  • 1
  • 2
  • 3
  • 4

3.2 判断字符串是否以某串开头或结尾

使用str.startswith()str.endswith()方法,注意:使用多个前后缀时用元组()表示!如(‘.py’, ‘cpp’),而不能用列表[]

files = ['a.py', 'b.cpp', 'c.py', 'd.java']
b_file = [file for file in files if file.startswith('b')]
print(b_file)
py_file = [file for file in files if file.endswith(('.py', 'cpp'))]
print(py_file)
>>> ['b.cpp']
>>> ['a.py', 'b.cpp', 'c.py']
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

3.3 字符串连接

s1+s2

res = ''
s = ['Tom', 'Jerry', 'Mike', 'Jim', 'Jack', 'Tom', 'Jerry', 'Mike', 'Jim', 'Jack']
for ss in s:
    res += ss
print(res) 
  • 1
  • 2
  • 3
  • 4
  • 5

s.join(字符串列表):将原字符串s依次连接字符串列表中的字符串。

res = ''
s = ['Tom', 'Jerry', 'Mike', 'Jim', 'Jack', 'Tom', 'Jerry', 'Mike', 'Jim', 'Jack']
res = res.join(s)
print(res) 
  • 1
  • 2
  • 3
  • 4

6. 类与对象

13.类相关
关键思想:私有化,模块化

class 类名(父类名):
   定义类变量 
   def __init__(self,参数):
   		#实例化此类对象时自动执行__init__()
   		self.定义此类的私有化模块;
   def 其他函数(self,参数):
   		...
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/213359
推荐阅读
相关标签
  

闽ICP备14008679号