0
点赞
收藏
分享

微信扫一扫

左神-算法与数据结构全阶班

上善若水山西太原 2022-02-13 阅读 72

### 左神-算法与数据结构全阶班

1. 易混杂操作

本节对一些 Python 易混杂的操作停止比照。

1.1 有放回随机采样和无放回随机采样download

import random
random.choices(seq, k=1)  # 长度为k的list,有放回采样
random.sample(seq, k)     # 长度为k的list,无放回采样
复制代码

1.2 lambda 函数的参数

func = lambda y: x + y          # x的值在函数运转时被绑定
func = lambda y, x=x: x + y     # x的值在函数定义时被绑定
复制代码

1.3 copy 和 deepcopy

import copy
y = copy.copy(x)      # 只复制最顶层
y = copy.deepcopy(x)  # 复制一切嵌套局部
复制代码

复制和变量别名分离在一同时,容易混杂:

a = [1, 2, [3, 4]]
# Alias.
b_alias = a  
assert b_alias == a and b_alias is a
# Shallow copy.
b_shallow_copy = a[:]  
assert b_shallow_copy == a and b_shallow_copy is not a and b_shallow_copy[2] is a[2]
# Deep copy.
import copy
b_deep_copy = copy.deepcopy(a)  
assert b_deep_copy == a and b_deep_copy is not a and b_deep_copy[2] is not a[2]
复制代码

对别名的修正会影响原变量,(浅)复制中的元素是原列表中元素的别名,而深层复制是递归的停止复制,对深层复制的修正不影响原变量。

1.4 == 和 is

x == y  # 两援用对象能否有相同值
x is y  # 两援用能否指向同一对象
复制代码

1.5 判别类型

type(a) == int      # 疏忽面向对象设计中的多态特征
isinstance(a, int)  # 思索了面向对象设计中的多态特征
复制代码

1.6 字符串搜索

str.find(sub, start=None, end=None); str.rfind(...)     # 假如找不到返回-1
str.index(sub, start=None, end=None); str.rindex(...)   # 假如找不到抛出ValueError异常
复制代码

1.7 List 后向索引

这个只是习气问题,前向索引时下标从0开端,假如反向索引也想从0开端能够运用~。

print(a[-1], a[-2], a[-3])
print(a[~0], a[~1], a[~2])
复制代码

2. C/C++ 用户运用指南

不少 Python 的用户是从以前 C/C++ 迁移过来的,这两种言语在语法、代码作风等方面有些不同,本节扼要停止引见。

2.1 很大的数和很小的数

C/C++ 的习气是定义一个很大的数字,Python 中有 inf 和 -inf:

a = float('inf')
b = float('-inf')
复制代码

2.2 布尔值

C/C++ 的习气是运用 0 和非 0 值表示 True 和 False, Python 倡议直接运用 True 和 False 表示布尔值。

a = True
b = False
复制代码

2.3 判别为空

C/C++ 对空指针判别的习气是 if (a) 和 if (!a)。Python 关于 None 的判别是:

if x is None:
    pass
复制代码

假如运用 if not x,则会将其他的对象(比方长度为 0 的字符串、列表、元组、字典等)都会被当做 False。

2.4 交流值

C/C++ 的习气是定义一个暂时变量,用来交流值。应用 Python 的 Tuple 操作,能够一步到位。

a, b = b, a
复制代码

2.5 比拟

C/C++ 的习气是用两个条件。应用 Python 能够一步到位。


if 0 < a < 5:
    pass
复制代码

2.6 类成员的 Set 和 Get

C/C++ 的习气是把类成员设为 private,经过一系列的 Set 和 Get 函数存取其中的值。在 Python 中固然也能够经过 @property、@setter、@deleter 设置对应的 Set 和 Get 函数,我们应防止不用要的笼统,这会比直接访问慢 4 - 5 倍。

2.7 函数的输入输出参数

C/C++ 的习气是把输入输出参数都列为函数的参数,经过指针改动输出参数的值,函数的返回值是执行状态,函数调用方对返回值停止检查,判别能否胜利执行。在 Python 中,不需求函数调用方停止返回值检查,函数中遇到特殊状况,直接抛出一个异常。

2.8 读文件

相比 C/C++,Python 读文件要简单很多,翻开后的文件是一个可迭代对象,每次返回一行内容。

with open(file_path, 'rt', encoding='utf-8') as f:
   for line in f:
       print(line)       # 末尾的\n会保存
复制代码

2.9 文件途径拼接

C/C++ 的习气通常直接用 + 将途径拼接,这很容易出错,Python 中的 os.path.join 会自动依据操作系统不同补充途径之间的 / 或 \ 分隔符:

import os
os.path.join('usr', 'lib', 'local')
复制代码

2.10 解析命令行选项

固然 Python 中也能够像 C/C++ 一样运用 sys.argv 直接解析命令行选择,但是运用 argparse 下的 ArgumentParser 工具愈加便当,功用愈加强大。

2.11 调用外部命令

固然 Python 中也能够像 C/C++ 一样运用 os.system 直接调用外部命令,但是运用 subprocess.check_output 能够自在选择能否执行 Shell,也能够取得外部命令执行结果。

import subprocess
# 假如外部命令返回值非0,则抛出subprocess.CalledProcessError异常
result = subprocess.check_output(['cmd', 'arg1', 'arg2']).decode('utf-8')  
# 同时搜集规范输出和规范错误
result = subprocess.check_output(['cmd', 'arg1', 'arg2'], stderr=subprocess.STDOUT).decode('utf-8')  
# 执行shell命令(管道、重定向等),能够运用shlex.quote()将参数双引号惹起来
result = subprocess.check_output('grep python | wc > out', shell=True).decode('utf-8')
复制代码

2.12 不反复造轮子

不要反复造轮子,Python称为batteries included即是指Python提供了许多常见问题的处理计划。

3. 常用工具

3.1 读写 CSV 文件

import csv
# 无header的读写
with open(name, 'rt', encoding='utf-8', newline='') as f:  # newline=''让Python不将换行统一处置
    for row in csv.reader(f):
        print(row[0], row[1])  # CSV读到的数据都是str类型
with open(name, mode='wt') as f:
    f_csv = csv.writer(f)
    f_csv.writerow(['symbol', 'change'])
# 有header的读写
with open(name, mode='rt', newline='') as f:
    for row in csv.DictReader(f):
        print(row['symbol'], row['change'])
with open(name, mode='wt') as f:
    header = ['symbol', 'change']
    f_csv = csv.DictWriter(f, header)
    f_csv.writeheader()
    f_csv.writerow({'symbol': xx, 'change': xx})
复制代码

留意,当 CSV 文件过大时会报错:_csv.Error: field larger than field limit (131072),经过修正上限处理

import sys
csv.field_size_limit(sys.maxsize)
复制代码

csv 还能够读以 \t 分割的数据

f = csv.reader(f, delimiter='\t')
复制代码

3.2 迭代器工具

itertools 中定义了很多迭代器工具,例如子序列工具:

import itertools
itertools.islice(iterable, start=None, stop, step=None)
# islice('ABCDEF', 2, None) -> C, D, E, F
itertools.filterfalse(predicate, iterable)         # 过滤掉predicate为False的元素
# filterfalse(lambda x: x < 5, [1, 4, 6, 4, 1]) -> 6
itertools.takewhile(predicate, iterable)           # 当predicate为False时中止迭代
# takewhile(lambda x: x < 5, [1, 4, 6, 4, 1]) -> 1, 4
itertools.dropwhile(predicate, iterable)           # 当predicate为False时开端迭代
# dropwhile(lambda x: x < 5, [1, 4, 6, 4, 1]) -> 6, 4, 1
itertools.compress(iterable, selectors)            # 依据selectors每个元素是True或False停止选择
# compress('ABCDEF', [1, 0, 1, 0, 1, 1]) -> A, C, E, F
复制代码

序列排序:

sorted(iterable, key=None, reverse=False)
itertools.groupby(iterable, key=None)              # 按值分组,iterable需求先被排序
# groupby(sorted([1, 4, 6, 4, 1])) -> (1, iter1), (4, iter4), (6, iter6)
itertools.permutations(iterable, r=None)           # 排列,返回值是Tuple
# permutations('ABCD', 2) -> AB, AC, AD, BA, BC, BD, CA, CB, CD, DA, DB, DC
itertools.combinations(iterable, r=None)           # 组合,返回值是Tuple
itertools.combinations_with_replacement(...)
# combinations('ABCD', 2) -> AB, AC, AD, BC, BD, CD
举报

相关推荐

0 条评论