文章数据
收藏(次)

【python数据分析】第三章 数据结构-函数-文件

加关注
数据结构和序列:
--------------------------------------------------------------------------------
元组:
用 tuple 可以将任意序列或迭代器转换成元组:
tuple([1,2,3])
tuple("aabbcc") #('a', 'a', 'b', 'b', 'c', 'c')

a = (1,2, 3)
a[1] # 使用序列访问

元组不可修改,元组中的元素如果是可修改对象,那么该元素的内容可以改
a = (1, 2, [1, 2])
#a[2] = [1,10] # error 不可修改元组的元素
a[2][1] = 10 # OK (1, 2, [1, 10]), 元组的元素是list,list内容是可以修改的


拼接:
(1,2) + (2,4) + (4, 5) # (1, 2, 2, 4, 4, 5)

(1,2)*4 #复制成4份 (1, 2, 1, 2, 1, 2, 1, 2) 对象本身并没有被复制,只是引用了它。


对等赋值:
tup = (1,2,(3,4))
a,b,(c,d) = tup

a,b = b,a #a b交换值

拆分:
li = [(1,2), (3,4), (5,6)]
for a, b in li:
print('a=%d,b=%d' %(a,b))

输出:
a=1,b=2
a=3,b=4
a=5,b=6


使用*xxx 用于接收剩余的赋值
va = (1,2,3,4,5)
a,b, *res = va
print('a={0}, b={1}, res={2}'.format(a,b,res)) #a=1, b=2, res=[3, 4, 5]


方法:count 统计某个元素出现次数
va = (1,2,3,1,4,5,1,6,7)
va.count(1)
--------------------------------------------------------------------------------
列表:
list(可转换对象) 变成列表
g = range(10) # g 是一个 range 对象
list(g)

添加删除数据
append
insert
pop
remove

使用 in 检查是否存在某个值
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
10 in a # false
10 not in a # true


扩展:
[1,2] + [3,2] #[1, 2, 3, 2], 新建一个列表,并copy元素,效率低


a = [1,2]
a.extend([2,3]) #[1, 2, 2, 3] 效率比 + 高


排序: sort, 里面还有参数,指定使用什么排序依据,比如字符串的长度 arr.sort(key=len)


二分搜索和维护已排序的列表
import bisect
a = [1, 3, 5, 8, 10]
bisect.bisect(a, 2) # 如果把2插入,那么应该放到哪个位置,并且还能保证有序, 返回1
bisect.insort(a, 4) # 插入一个数据

切片:
格式 start:stop:step

a = [1, 3, 4, 5, 8, 10]
a[1:3] # [3, 4] 1:3 但不包含3, 前闭后开区间

start:stop 都是可以省略的,表示从开头到结尾,也可以是负数,表示从后到前的操作

a[-1:] # 输出 [10] why? 省略了 stop,表示到结束,-1 表示从后面第一个元素开始,然后到结束,就是[10]
a[-1::-1] # 将a倒叙 [10, 8, 5, 4, 3, 1] # -1 从最后到结束,但是步长是-1,正好把 a 倒叙
a[::-1] # 倒叙

书上的图片对理解 -1 的位置非常有帮助, 书上把-1的位置定在 倒数第1和倒数第2的缝隙处
所有的下标都是缝隙处, a[-5:-2] 这样就是取 -2 所在缝隙 和 -5 所在缝隙之间的数据

但是这样理解麻烦,应该是理解成 -1 就是倒数第1的元素,-2是倒数第二的元素,
a[-5:-2] 还是 倒数第5的元素 到 倒数第2的元素,由于前开后闭,不包括倒数第2的数据
这样,不管是正数还是负数,逻辑都是统一的了。前闭后开区间



enumerate 函数:变量list时想要获得下标
可以这样:但不好看
a = [10, 8, 5, 4, 3, 1]
idx = 0
for v in a:
print('%d--%d' % (idx, v))
idx += 1

使用 enumerate
a = [10, 8, 5, 4, 3, 1]
for i, value in enumerate(a):
print('%d--%d' % (i, value))



排序2: sorted
sorted 是全局函数
sort 是 list 的成员方法

sorted(list)
list.sort()

用法差不多,sorted也能有 sort那样指定排序依据的参数


zip 函数:zip 可以将多个列表、元组或其它序列成对组合成一个元组列表
每个元组是多个原数据对应位置上的数据组成

s1 = [1,2,3]
s2 = ['a', 'b', 'c']
z = zip(s1,s2) # <zip at 0x1849d663080>
list(z) #[(1, 'a'), (2, 'b'), (3, 'c')]

zip 可以处理任意多的序列,元素的个数取决于最短的序列:
s1 = [1,2,3]
s2 = ['a', 'b', 'c']
s3 = [True, False]
z = zip(s1,s2,s3)
list(z) # [(1, 'a', True), (2, 'b', False)] 取决最短的,长的丢了

作用:有名字的列表,有年龄的列表,有编号的列表,三个列表组合起来才是人员的信息,
还有逆向操作,比如有这样的列表,想把名字单独抽取出来怎么做:

inf = [(111, 'zhangsan', 10), (222, 'lisi', 12), (333, 'wangwu', 13)]
nos,names,ages = zip(*inf)
print('nos:{0} ---- names:{1} ---- ages:{2}'.format(nos, names, ages))

输出:
nos:(111, 222, 333) ---- names:('zhangsan', 'lisi', 'wangwu') ---- ages:(10, 12, 13)


reversed 函数:全局函数 是一个生成器:反转一个序列
list(reversed(a))
--------------------------------------------------------------------------------
字典:

in 判断 是否存在某个 key
del 删除
pop 删除

mapping = dict(zip(range(5), reversed(range(5))))


字典的值可以是任意Python对象,而键通常是不可变的标量类型(整数、浮点型、
字符串)或元组(元组中的每个元素必须是不可变的)。这被称为“可哈希性”。可以
用 hash 函数检测一个对象是否是可哈希的(可被用作字典的键):

hash((1, 2, [2, 3])) # 可变对象,不可hash 报错,不能作为 dict 的key
--------------------------------------------------------------------------------
集合: set, 无序,不可以重复

并集: union 或者 |
交际: intersection 或者 &
很多常用的集合方法

a = [1,2,3]
s = set(a)
================================================================================
列表、集合和字典推导式: [expr for val in collection if condition]

等价于:
result = []
for val in collection:
if condition:
result.append(expr)

推到式还能嵌套, 要求可迭代对象也是嵌套可迭代的,比如 list 中的元素还是 list


使用推到式得到列表
s = ['a', 'bb', 'ccc', 'ddd']
[x.upper() for x in s if len(x) > 2] # ['CCC', 'DDD']


使用推到式得到字典
s = ['a', 'bb', 'ccc', 'ddd']
m = {x:len(x) for x in s} # {'a': 1, 'bb': 2, 'ccc': 3, 'ddd': 3}

使用推到式得到 set , set使用{} 的,是只有key 没有value 的字典
s = ['a', 'bb', 'ccc', 'ddd']
m = {x for x in s}


嵌套:
inf = [(111, 'zhangsan', 10), (222, 'lisi', 12), (333, 'wangwu', 13)]
[x for ii in inf for x in ii]
输出: [111, 'zhangsan', 10, 222, 'lisi', 12, 333, 'wangwu', 13]

for ii in inf 得到的是 一个个 (111, 'zhangsan', 10)
for x in ii x 就是变量 (111, 'zhangsan', 10) 中的每个元素,
[x for ii in inf for x in ii] 一层遍历得到三个元组,元组再次遍历得到内容,组成推导式
================================================================================
函数
================================================================================
函数返回多个值:

def f():
a = 5
b = 6
c = 7
return a, b, c
a, b, c = f()

--------------------------------------------------------------------------------
内建函数 map(函数, 可迭代对象), 给可迭代元素依次 应用函数,
list(map(str.title, ['aaa', 'bBB', 'CCC', 'Ddd']))
--------------------------------------------------------------------------------
lambda:
格式 lambda 参数列表:表达式 其中表达式的结果是返回值
lambda x, y: x + y
--------------------------------------------------------------------------------
柯里化:
就是将一个已经存在的函数,把函数的某个参数变成固定的参数,形成一个新的函数
新的函数不再需要传递固定的那个参数

比如:
def add(a, b):
return a + b

add(1,2)

#固定一个参数,比如 b,相当于把参数b柯里化:
def addFive(a):
return add(a, 5)

addFive(10)

使用 partial,能够简化柯里化,但是不能指定对哪个参数柯里化,
from functools import partial

addThr = partial(add,3) # functools.partial(<function add at 0x000001849DDB9310>, 3)
addThr(1) # 4

用 lambda 表达式 柯里化:
addTwo = lambda x: add(x, 2)
addTwo(3)
--------------------------------------------------------------------------------
生成器:
生成器是一个表达式,等需要的时候去计算,而不是一开始就计算完成,防止数据大,OOM

自定义生成器: 方法里面加一个 yield 就是生成器,不是函数了
def ge():
yeild xxx


生成器表达式:(x:for x in it) 是小括号, [],{} 是list 和 map,set的推导式
a = [1,2,3,4,5]
[x*x for x in a] #[1, 4, 9, 16, 25]
{x+1 for x in a} #{2, 3, 4, 5, 6}
{x+1:x*x for x in a} #{2: 1, 3: 4, 4: 9, 5: 16, 6: 25}

(x*x for x in a) # 生成器,需要next,或者迭代
(x+1 for x in a) # 生成器
(x+1:x*x for x in a) # error 生成器不能是 dict


it = (x*x for x in a)
下面三种方式取值,前两种取完后会报错(最后一个数据取出后继续取值)
it.__next__()
next(it)
for x in it: # 不会报错是因为 for 循环捕获了这个异常
print(x)


itertools包:
itertools 中有很多函数,就是对一个列表中元素执行某个函数:
比如 itertools.groupby 给可迭代对象的元素,按照某种规则分组
至于里面还有哪些函数,自行查阅


import itertools
first_letter = lambda x: x[0]
name = ['Axx', 'Asd', 'Cxx', 'Bdd', 'Bgg', 'Cgs', 'BKK']
for letter, names in itertools.groupby(name, first_letter):
print(letter, list(names))

输出:必须是相邻的,才能分到一组中
A ['Axx', 'Asd']
C ['Cxx']
B ['Bdd', 'Bgg']
C ['Cgs']
B ['BKK']
--------------------------------------------------------------------------------
异常处理
try:
except 异常类型:


try:
except (异常类型1, 异常类型2):


try:
finally:


try:
except: #有异常执行这个
else: #没有异常执行这个
finally:
================================================================================
文件和操作系统:
f = open('path')
f.close

用with语句可以可以更容易地清理打开的文件:
with open(path) as f:
lines = [x.rstrip() for x in f]
这样可以在退出代码块时,自动关闭文件。

open 参数可以指定读写模式
--------------------------------------------------------------------------------



>> 目录 << 


 

分享
收藏
点赞人
举报
文章标签
评论列表

推荐

暂无推荐