记录一下python的数据结构
2016-10-20 22:16
309 查看
记录一下python的数据结构
1 list
\>>> classmates = ['bob','mike'] \>>> classmates[0] # 从0开始索引 \>>> classmates[-1] # 直接获取最后一个元素;以此类推,[-2]为倒数第二个元素 ####python中的数据索引和matlab的相左,python从0到元素个数最后一位的前一位,而matlab则是从1到元素个数的最后一位 \>>> classmates,append('adam') #末尾追加元素 \>>> classmates.insert(1,'jack') #索引插入 \>>> classmates.pop() #除去末尾元素 \>>> classmates.pop(i) #索引删除 \>>> classmates[1] = 'sarah' # 索引赋值 \>>> school = ['classmates1','classmates2',['mike','jack']] \>>> school[2][1] = 'mike'
2 array
标准安装的Python中用列表(list)保存一组值,可以用来当作数组使用,不过由于列表的元素可以是任何对象,因此列表中所保存的是对象的指针。这样为了保存一个简单的[1,2,3],需要有3个指针和三个整数对象。对于数值运算来说这种结构显然比较浪费内存和CPU计算时间。 此外Python还提供了一个array模块,array对象和列表不同,它直接保存数值,和C语言的一维数组比较类似。但是由于它不支持多维,也没有各种运算函数,因此也不适合做数值运算。 NumPy的诞生弥补了这些不足,NumPy提供了两种基本的对象:ndarray(N-dimensional array object)和 ufunc(universal function object)。ndarray(下文统一称之为数组)是存储单一数据类型的多维数组,而ufunc则是能够对数组进行处理的函数。 所以使用前,需要`import numpy as np` \>>> a = np.array([1,2,3,4]) \>>> b = np.array([[1,2,3][4,5,6]]) \#上面例子中的参数序列的元素都是整数,因此所创建的数组的元素类型也是整数,并且是32bit的长整型。 \#可以通过dtype参数在创建时指定元素类型: \>>> np.array([[1, 2, 3, 4],[4, 5, 6, 7], [7, 8, 9, 10]], dtype=np.float) = array([[ 1., 2., 3., 4.], [ 4., 5., 6., 7.], [ 7., 8., 9., 10.]]) \>>> np.array([[1, 2, 3, 4],[4, 5, 6, 7], [7, 8, 9, 10]], dtype=np.complex) = array([[ 1.+0.j, 2.+0.j, 3.+0.j, 4.+0.j], [ 4.+0.j, 5.+0.j, 6.+0.j, 7.+0.j], [ 7.+0.j, 8.+0.j, 9.+0.j, 10.+0.j]]) \>>> a.shape = (4,) \>>> b.shape = (2,3) \>>> b.shape = 3,2 # 对b进行调整 \>>> b = ([[1,2][3,4][5,6]]) \>>> b.shape = 2,-1 \>>> b = ([[1,2,3][4,5,6]]) \>>> d = a.reshape((2,2)) #创建1个改变了尺寸的新数组,且a和d共享内存,改变其中一个元素,会同时修改另一个 \>>> a = np.arange(10) \>>> a = [0,1..,8,9] \>>> np.arange(0,1,0.1) #arange函数类似于range函数,通过指定开始值、终值和步长来创建一维数组,当然也是不包括终值的 = array([ 0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]) \>>> np.arange(0, 60, 10).reshape(-1, 1) + np.arange(0, 6) = array([[ 0, 1, 2, 3, 4, 5], [10, 11, 12, 13, 14, 15], [20, 21, 22, 23, 24, 25], [30, 31, 32, 33, 34, 35], [40, 41, 42, 43, 44, 45], [50, 51, 52, 53, 54, 55]]) \>>> a[5] #用整数做下标 \>>> a[3:5] #用范围做下标获取数组切片,包括a[3]但不包括a[5] = array([3,4]) \>>> a[:5] array([0,1,2,3,4]) \>>> a[:-1] #用法同list \>>> a[2:4] = 100,101 # 索引修改值 \>>> a[1:-1:2] #第三个参数表示步长 = array([1, 3, 5, 7]) \>>> a[::-1] #数组头尾颠倒,省略范围的开始和结束 = array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0]) \>>> a[5:1:-2] #步长为负,则起始点要大于结束点 = array([5, 3]) \>>> b = a[3:7] #通过索引产生的新数组b,和a共享数据空间
3 tuple
tuple和list很像,但是tuple一旦初始化就不能修改。\>>> classmates = ('Michael', 'Bob', 'Tracy')
classmates这个tuple就不能改变了;
tuple没有append(),insert()这样的方法;
其他获取元素的方法和list是一样的,可以正常地使用classmates[0],classmates[-1],但不能赋值成另外的元素;
因为tuple不可变,所以代码更安全。如果可能,能用tuple代替list就尽量用tuple。
>>> t = (1, 2) #定义一个tuple时,tuple的元素就必须被确定下来
>>> t
= (1, 2)
>>> t = () #定义一个空的tuple
>>> t
= ()
>>> t = (1,) #定义只有1个元素的tuple,需要加逗号
>>> t
= (1,)
>>> t = (‘a’, ‘b’, [‘A’, ‘B’]) # 将元素定义为list,尽管tuple指向不能变,但是list的指向可以改变,那tuple的内容就可以改变了
>>> t2 = ‘X’
>>> t2 = ‘Y’
>>> t
= (‘a’, ‘b’, [‘X’, ‘Y’])
4 dict
python内置,在其他语言中称为map使用键-值(key-value)存储
优点是查找速度非常快
>>> d = {‘Michael’: 95, ‘Bob’: 75, ‘Tracy’: 85}
>>> d[‘Michael’]
= 95
>>> d[‘Adam’] = 67 #通过key值放入数据
>>> d[‘Adam’]
= 67
>>> ‘Thomas’ in d #通过in判断来key是否存在
= False
>>> d.get(‘Thomas’) #dict提供get方法,如果key不存在,可以返回None,或者自己指定的value:
>>> d.get(‘Thomas’, -1)
= -1
>>> d.pop(‘Bob’) #删除key用pop(key)方法,对应的value也会从dict中删除
>>> d
= {‘Michael’: 95, ‘Tracy’: 85}
>>> D.has_key(key) #有该键返回TRUE,否则FALSE
>>> D.keys() #返回字典键的列表
>>> D.values() #返回字典键的列表
>>> D.items()
>>> D.update(dict2) #增加合并字典
>>> D.popitem() #得到一个pair,并从字典中删除它;已空则抛异常
>>> D.clear() #清空字典,同del dict
>>> D.copy() #拷贝字典
>>> D.cmp(dict1,dict2) #比较字典(优先级为元素个数、键大小、键值大小): 第一个大返回1,小返回-1,一样返回0
#dictionary的复制
>>> dict1 = dict #别名,指向同一个字典
>>>dict2=dict.copy() #克隆,指向不同的字典
注意:
dict内部存放的顺序和key放入的顺序没有关系;dict和list比较:
dict查找和插入的速度极快,不会随着key的增加而增加;
dict需要占用大量的内存,内存浪费多;
list查找和插入的时间随着元素的增加而增加;
list占用空间小,浪费内存很少。
dict的key必须是不可变对象;因为dict根据key来计算value的存储位置(哈希算法)。要保证hash的正确性,作为key的对象就不能变。python中,字符串、整数等都是不可变的,因此,可以放心地作为key。而list是可变的。
dict的value可以是任意类型
5 set
set类似于dict,是一组不重复的key的集合,但不存储value。\>>> s = set([1, 2, 3])#要创建一个set,需要提供一个list作为输入集合 \>>> s = set([1, 2, 3]) #传入的参数[1, 2, 3]是一个list,显示的set([1, 2, 3])只是告诉你这个set内部有1,2,3这3个元素,显示的[]并不表示这是一个list \>>> s = set([1, 1, 2, 2, 3, 3]) \>>> s = set([1, 2, 3])#重复元素在set中自动被过滤 \>>> s.add(4) #通过add(key)方法可以添加元素到set中 \>>> s = set([1, 2, 3, 4]) \>>> s.add(4) \>>> s = set([1, 2, 3, 4]) \>>> s.remove(4) #通过remove(key)方法可以删除元素 \>>> s = set([1, 2, 3]) \>>> s1 = set([1, 2, 3]) #set可以看成数学意义上的无序和无重复元素的集合 \>>> s2 = set([2, 3, 4])#因此,两个set可以做数学意义上的交集、并集等操作 \>>> s1 & s2 = set([2, 3]) \>>> s1 | s2 = set([1, 2, 3, 4])
注意:
set的原理和dict一样唯一区别仅在于set没有存储对应的value
set同样不可以放入可变对象(比如list),因为无法判断两个可变对象是否相等,也就无法保证set内部“不会有重复元素”
6 string
计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理。最早的计算机采用8个比特(bit)作为一个字节(byte),一个字节能表示的最大的整数就是255(二进制11111111=十进制255),如果要表示更大的整数,就必须用更多的字节。
比如两个字节可以表示的最大整数是65535,4个字节可以表示的最大整数是4294967295。
由于计算机是美国人发明的,所以最早只有127个字母被编码到计算机里:大小写英文字母、数字和一些符号,这个编码表被称为ASCII编码。
所以,中国制定了GB2312编码,用来把中文编进去。
但全世界有上百种语言,日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr里,各国的标准不可避免地出现了冲突,所以在多语言混合的文本中,显示出来会有乱码。
Unicode应运而生。
Unicode把所有语言都统一到一套编码里,这样就不会再有乱码问题了。
Unicode标准也在不断发展,但最常用的是用两个字节表示一个字符(非常偏僻的字符,就需要4个字节)。
现代操作系统和大多数编程语言都直接支持Unicode。
ASCII编码和Unicode编码的区别:ASCII编码是1个字节,而Unicode编码通常是2个字节。
字母A用ASCII编码是十进制的65,二进制的01000001;
如果把ASCII编码的A用Unicode编码,只需要在前面补0就可以,因此,A的Unicode编码是00000000 01000001。
尽管统一成Unicode编码,乱码问题从此消失了。但是如果文本基本上全部是英文的话,用Unicode编码比ASCII编码需要多一倍的存储空间,在存储和传输上就十分不划算。
所以,出现了把Unicode编码转化为“可变长编码”的UTF-8编码。
UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节(所以ASCII编码实际上可以被看成是UTF-8编码的一部分),汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。
最后,在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。
\>>> ord('A') #字母和对应的数字相互转换 = 65 \ >>> chr(65) = 'A' \>>> print u'中文' #以unicode表示的字符用u'..'表示 = 中文 \>>> u'ABC'.encode('utf-8')#把Unicode编码表示的字符串转换为UTF-8 = 'ABC' \>>> 'abc'.decode('utf-8') #把UTF-8编码表示的字符串转换为Unicode字符串 = u'abc'
#!/usr/bin/env python #告诉Linux/OS X系统,这是一个Python可执行程序,Windows系统会忽略这个注释;
# -*- coding: utf-8 -*- #告诉Python解释器,按照UTF-8编码读取源代码
>>> string = "Hello My friend" >>> print string[0] = H >>> print string[0:5] = Hello #字符串包含判断操作符:in,not in >>> print 'He' in string = True >>> print 'sHe' in string = False #后面跟数字表示字符串重复的次数,比如 print 'hello'*5 >>> hellohellohellohellohello #string模块,还提供了很多方法,如 S.find(substring, [start [,end]]) #可指范围查找子串,返回索引值,否则返回-1 S.rfind(substring,[start [,end]]) #反向查找 S.index(substring,[start [,end]]) #同find,找不到时产生ValueError异常 S.rindex(substring,[start [,end]])#同上反向查找 S.count(substring,[start [,end]]) #返回找到子串的个数 S.lowercase() S.capitalize() #首字母大写 S.lower() #转小写 S.upper() #转大写 S.swapcase() #大小写互换 S.split(str, ' ') #将string转list,以空格切分 S.join(list, ' ') #将list转string,以空格连接 #处理字符串的内置函数 len(str) #串长度 cmp("my friend", str) #字符串比较。第一个大,返回1 max('abcxyz') #寻找字符串中最大的字符 min('abcxyz') #寻找字符串中最小的字符 #string的转换 float(str) #变成浮点数,float("1e-1") 结果为0.1 int(str) #变成整型, int("12") 结果为12 int(str,base) #变成base进制整型数,int("11",2) 结果为2 long(str) #变成长整型 long(str,base) #变成base进制长整型, #字符串的格式化(注意其转义字符,大多如C语言的) str_format % (参数列表) #参数列表是以tuple的形式定义的,即不可运行中改变 >>>print ""%s's height is %dcm" % ("My brother", 180) = My brother's height is 180cm
关于格式化输出:
%d 整数
%f 浮点数
%s 字符串
%x 十六进制整数
格式化整数和浮点数还可以指定是否补0和整数与小数的位数:比如 %02d 和 %.2f
如果不太确定应该用什么,%s永远起作用,它会把任何数据类型转换为字符串
对于Unicode字符串,用法完全一样,但最好确保替换的字符串也是Unicode字符串:比如 u’Hi, %s’ % u’Michael’
用%%来表示一个%
如果只有一个%?,括号可以省略
7 不可变对象
list为可变对象。string为不可变对象对于不可变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容;相反,这些方法会创建新的对象并返回,这样就保证了不可变对象本身永远是不可变的
本篇博客主要参考自
《用python做科学计算》
《Python自学笔记之基础内容回顾》
《Python 列表(list)、字典(dict)、字符串(string)常用基本操作小结 》
《 Python list 操作》
《列表(list), 元祖(tuple), 字典(dict), 字符串(string), 集合(set) 的基本方法 》
《python 2.7教程》
相关文章推荐
- Python学习记录-3-简明Python教程-数据结构
- Python cookbook(数据结构与算法)根据字段将记录分组操作示例
- Python Tutorial第五章 数据结构
- python 数据结构
- Python学习(七) -- 数据结构
- python学习总结之数据结构
- Python学习--数据结构
- 几个数据仓库方面的资源,记录一下。
- python 数据结构
- python笔记之数据结构
- python 教程 第七章、 数据结构
- 外设移除区别/终端记录/重设密码/python测试/数据拷贝最大限度
- Python中数据结构 列表 元组 字典 序列
- 打印python的ctype定义的结构中的数据
- 记录一下ORACLE数据隐式转换规则
- 七、Python:数据结构
- python 数据结构
- Python 2.7 Tutorial —— 数据结构
- 简单分析一下uboot的主要数据结构
- Python学习笔记(1)--数据结构