因为需要准备美赛,所以开始进行数模和python数据分析的学习,之前呢,断断续续看了这本书的第三章,本人决定从第三章开始进行学习笔记的更新,数模部分后续也会出一部分。
至于为什么会跳过前两章,则是有两点原因:
- 笔者使用的编译环境是Pycharm2020,和Anaconda3, 而该书是基于Jupyter和IPython,第一章主要是编译器和编译环境的内容,笔者也没去看。
- 第二章则是python的一些基础语法,这些东西基本上在笔者刚上大一时在计算机基础这门课程接触了解过了,所以笔者也没怎么看。
该章的标题是“内建数据结构、函数及文件”,所以该章也会分成这样的三个板块进行知识点讲解,本文中对文件的部分只会简单提及,重点在数据结构和函数两个部分
还有一点:本文很长,没有感情,全是干货,希望能对你们有所帮助
定义:固定长度、不可变的python对象序列, 最简单的创建方式用逗号分隔序列值
从上面的定义,我们可以知道
tup = 1, 2, 4 print(tup + (2, 3) * 2)
元组不可变
元组一旦创建,各个位置上的对象是无法被修改的,但是像元组中对象可变,例如列表,则可以在内部修改
# tuple函数 将任意序列或者迭代数转换成元组 tup = tuple(['foo', [1, 2], True]) # tup[2] = False 错误,元组不可变 tup[1].append(3) print(tup)
元素是Python对象,见上面的例子
其实就是把元组的元素进行拆分,分别赋值给相应变量
# tuple函数 将任意序列或者迭代数转换成元组 tup = tuple(['foo', [1, 2], True]) # tup[2] = False 错误,元组不可变 tup[1].append(3) print(tup) a , (b,d,e), c = tup print(a, b, c, d, e)
实例方法较少,常见的方法是count方法,用于 计量某个元素在元组中出现的次数:
a = (1, 2, 2, 2, 3, 4, 2) print(a.count(2))
长度可变,内容可修改,使用[]或者list类型函数创建
append和insert
append到将元素添加到列表尾部,而insert则可以在对应位置添加元素
_list = [1, 2, 3, 4] _list.append(5) print(_list) _list.insert(0, 0) print(_list)
pop和remove
pop对应insert,append对应remove,pop 移除特定位置的元素,remove会找到列表中第一个符合要求的元素并移除。
_list = [1, 2, 3, 4] _list.append(5) print(_list) _list.insert(0, 0) print(_list) _list.pop(0) print(_list) _list.remove(3) print(_list)
in 和 not, in判断值是否在列表中,not判断是否不在列表
两种方式: + 和 extend方法
extend 的代价较小,性能更优
sort 函数,默认会按升序排列
其中的key选项,是一个二级排序,用于生成排序值的函数
b = ['saw', 'small', 'He', 'foxes', 'six'] b.sort(key = len) print(b)
python 内建的bisect 模块实现了二分搜索和已排序列表的插值。其中bisect为找到元素应当被插入的位置,并保持序列排序,而insort会将元素插入到相应位置
import bisect c = [1, 2, 2, 2, 3, 4, 7] print(bisect.bisect(c, 2)) bisect.insort(c, 6) print(c)
使用切片符号可以对大多数序列类型选取子集,它的基本形式就是[start:stop]
其完整形式可以是[start:stop:step],start表示开始位置的索引,stop结束位,step为步进值
对数据建立索引,会对序列构造应一个字典,元素值 :序列值(索引)
thisList = ['a', 'b', 'v'] mapping = {} for i, v in enumerate(thisList): mapping[v] = i print(mapping)
会返回一个任意序列中的元素新建的已排序列表
print(sorted([43,4, 2,565,3]))
将序列的元素配对、新建一个元组构成的列表,可以处理任意长度的序列,生成列表长度由最短的序列决定
seq1 = ['foo', 'bar', 'baz'] seq2 = ['one', 'two', 'three'] zipped = zip(seq1, seq2) print(list(zipped)) seq3 = [False, True] print(list(zip(seq1,seq2 ,seq3)))
就是将序列倒序排列
很好理解就是 C++中的 unordered_map<object, object>, object表示对象类型,字典是键值对结构,键和值都是Python对象
访问和插入或设置以及检查 基本上和 列表、元组一样
del关键字删除键, pop方法删除值
key方法和value方法会分别提供字典键、值得下迭代器
合并方法为update
mapping = dict(zip(range(5), reversed(range(5)))) print(mapping)
默认值主要是为了查找和删除时,出现未在字典中的键,get方法和pop方法都有默认值
其实就是用hash方法检查是否可以哈希化——键必须是不可变的对象
无序且元素唯一的容器,和字典类似,但是只有键没有值,创建方式有两种,set方法或者字面值集与大括号的语法。
集合支持数学上的集合操作,例如联合、交集、差集等,下面是操作表
函数 | 替代方法 | 描述 |
---|---|---|
a.add(x) | N/A | 将元素x加入到集合a |
a.clear() | N/A | 将集合重置为空,清空所有元素 |
a.remove(x) | N/A | 从集合a移除元素x |
a.pop() | N/A | 移除任意元素,如果集合是空集则抛出keyError |
a.union(b) | a | b | a 和 b 中的所有不同元素 |
a.update(b) | a |= b | 将 a 的内容设置为 a 和 b 的并集 |
a.intersection(b) | a & b | a、b中同时包含的元素 |
a.intersection_update(b) | a &= b | 将a的内容设置为a 和 b 的交集 |
a.difference(b) | a - b | 在a 不在 b 的元素 |
a.difference_updated(b) | a -= b | 将 a 的内容设置为在 a 不在b的元素 |
a.symmsymmetric_difference(b) | a^b | 所有在a或b中,但不是同时在a、b中的元素 |
a.symmetric_difference_update(b) | a ^= b | 将a的内容设上一行所诉元素 |
a.issubset(b) | N/A | 如果a包含于b返回True |
a.issuperset(b) | N/A | 如果a包含b返回True |
a.isdisjoint(b) | N/A | a、b没有交集返回True |
这部分特性就在于可以使得我们可以过滤一个容器的元素并用一种简明的表达式转换传递给过滤器的元素,从而生成一个新的列表、集合或者字典
以生成列表为例子
strings = ['a', 'bat', 'as', 'car', 'dove', 'python', 'cpp', 'java'] List = [x for x in strings if len(x) > 2] print(List)
这种推导式可以嵌套!但是如果嵌套层数过多,会影响代码的可读性
函数是Python中最重要、最基础的代码组织和代码复用方式。通过给一组Python语句一个函数名,形成的函数可以使你的代码更加可读。
函数有两种连接变量的方式:全局、本地
而在python中有一种更贴切地描述变量作用域的名称是命名空间。在函数内部,任意变量都是默认分配到本地空间的,本地命名空间是在函数调用时生成,其实做个概念就是笔者在C++面向对象时接触到的内存的栈区。
python函数有一个很不错的特性就是返回多值
def f(): a = 5 b = 6 c = 7 return a, b, c a, b, c = f()
上诉代码其实就是函数 f 返回了一个元组对象,然后元组又按照我们之前所学的方式就是利用元组拆包方式,将函数返回的元组拆分成多个变量接收。
其实就是python函数可以当作对象来使用
使用lambda关键字定义匿名函数, 该关键字仅表达“我们声明一个匿名函数”的意思
strings = ['foo', 'card', 'bar', 'aaaa', 'abab'] strings.sort(key=lambda x : len(set(list(x)))) print(strings)
其实就是对于函数部分应用的方式从已有的函数中衍生出新的函数
生成器是构造新的可遍历对象的一种非常简洁的方式。普通函数执行并一次返回单个结果,而生成器则”惰性“地返回一个多结果序列,在每一个元素产生之后暂停,知道下一个请求。
类似列表、字典、集合推导式,可以使用生成器表达式生成生成器
gen = (x ** 2 for x in range(5)) print(gen) print(list(gen))
直接看代码
def attempt_float(x): try: return float(x) except: return x print(attempt_float('2343.3243')) print(attempt_float('sodfnfd'))
这部分基本上就不会讲啥了,注意几个函数read、tell、seek,其中seek是可以将句柄位置改变到文件中特定地字节。
然后注意下python的文件模式就可以了
模式 | 描述 |
---|---|
r | 只读模式 |
w | 只写模式,创建新文件(清除路径下的同名文件) |
x | 只写模式,创建新文件,但路径下存在同名文件则会创建失败 |
a | 添加到已存在的文件(如果不存在则创建) |
r+ | 读写模式 |
b | 二进制文件模式,添加到别的模式中(rb, wb) |
t | 文件的文本模式(自动将字节解码为Unicode),如果没有指明模式,则默认使用此模式,也可以添加到别的模式中。 |