python中数据结构函数汇总

python中数据结构

python中的数据结构有字符串str,列表list,元组tuple,字典dict,集合set

其中字符串和元组是不可变的

列表,字典和集合都是可以改变的

一.字符串str

标准的序列操作(列表操作)都是适用于字符串的(索引、切片、乘法、成员资格检查、长度、最小值、最大值等)都是适用于字符串的

但是字符串是不可变的,所以所有的元素赋值和切片赋值都是非法的

1.去除空格或者特定字符

strip括号中设置参数去除特定的字符的

s.strip()
s.lstrip()
s.rstrip()
s.strip().lstrip().rstrip(',') 

2.赋值,连接,比较字符串

#strcpy(str1,str2)
#赋值字符串
str1 = 'strcpy'
str2 = str1
str1 = 'strcpy2'

#使用 + 拼接字符串
str3=str1+str2

#使用join来连接字符串,用特定的字符连接
delimiter = ','
mylist = ['Brazil', 'Russia', 'India', 'China']
print delimiter.join(mylist)


print(str2)
#比较字符串
print(cmp(str1,str2))

3.查找字符和查找字符串

#使用find函数在字符串中查找字符串
str1 = 'abcdefg'
str2 = 'cde'
print str1.find(str2)

#使用index来查找字符
# < 0 为未找到
str1 = 'strchr'
str2 = 's'
nPos = str1.index(str2)
print nPos

#使用and来扫描是否包含字符串
str1 = '12345678'
str2 = '456'
#str1 and chars both in str1 and str2
print len(str1 and str2)

#与find()相同,只是在S中没有substr时,会返回一个运行时错误 
S.rfind(substr, [start, [end]]) 
#返回S中最后出现的substr的第一个字母的标号,如果S中没有substr则返回-1,也就是说从右边算起的第一次出现的substr的首字母标号 
S.rindex(substr, [start, [end]])

4.两边填充居中

#使用center来进行居中字符串
str1="hello python"
str1.center(39,"*")

5.替换字符串

#使用repalce来替换字符串
S.count(substr, [start, [end]]) #计算substr在S中出现的次数 
S.replace(oldstr, newstr, [count]) 
#把S中的oldstar替换为newstr,count为替换次数。这是替换的通用形式,还有一些函数进行特殊字符的替换
#可以使用translate进行替换但是需要组成一个转换表进行替换,这是一个单字符的替换

6.字符串中的测试函数

S.startswith(prefix[,start[,end]]) 
#是否以prefix开头 
S.endswith(suffix[,start[,end]]) 
#以suffix结尾 
S.isalnum() 
#是否全是字母和数字,并至少有一个字符 
S.isalpha() #是否全是字母,并至少有一个字符 
S.isdigit() #是否全是数字,并至少有一个字符 
S.isspace() #是否全是空白字符,并至少有一个字符 
S.islower() #S中的字母是否全是小写 
S.isupper() #S中的字母是否便是大写 
S.istitle() #S是否是首字母大写的

7.字符串的类型转换函数

string.atoi(s[,base]) 
#base默认为10,如果为0,那么s就可以是012或0x23这种形式的字符串,如果是16那么s就只能是0x23或0X12这种形式的字符串 
string.atol(s[,base]) #转成long 
string.atof(s[,base]) #转成float

8.截取字符串

str = '0123456789'
print str[0:3]    #截取第一位到第三位的字符
print str[:]      #截取字符串的全部字符
print str[6:]     #截取第七个字符到结尾
print str[:-3]    #截取从头开始到倒数第三个字符之前
print str[2]      #截取第三个字符
print str[-1]     #截取倒数第一个字符
print str[::-1]   #创造一个与原字符串顺序相反的字符串
print str[-3:-1]  #截取倒数第三位与倒数第一位之前的字符
print str[-3:]    #截取倒数第三位到结尾
print str[:-5:-3] #逆向截取,倒数第一位与倒数第五位之间的字符,步长为3

二.列表

       列表是Python中最基本的数据结构,列表是最常用的Python数据类型,列表的数据项不需要具有相同的类型。列表中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推。
       Python有6个序列的内置类型,但最常见的是列表和元组。序列都可以进行的操作包括索引,切片,加,乘,检查成员。此外,Python已经内置确定序列的长度以及确定最大和最小的元素的方法。

python中的6个内建的序列,即列表元组、字符串、Unicode字符串、buffer对象和 xrange 对象。序列通用的操作包括:索引、长度、组合(序列相加)、重复(乘法)、分片、检查成员、遍历、最小值和最大值。

列表中的对象可以是不同的数据类型

1.创建,访问和更新列表

#创建列表
list1 = ['physics', 'chemistry', 1997, 2000]
list2 = [1, 2, 3, 4, 5 ]
list3 = ["a", "b", "c", "d"]
#访问列表中的值
print(list1[0])
print(list2[0])
print(list3[1:3])
#更新列表
list2[2]='2000'

2.添加和删除元素

#使用del来进行删除列表元素
list1 = ['physics', 'chemistry', 1997, 2000]
del list1[2]

#使用append来进行添加列表项
s=['physics','chemistry']
s.append("wangtao")

3.列表脚本操作符详解

列表对 + 和 * 的操作符与字符串相似。+ 号用于组合列表,* 号用于重复列表。

Python 表达式结果描述
len([1, 2, 3])3长度
[1, 2, 3] + [4, 5, 6][1, 2, 3, 4, 5, 6]组合
['Hi!'] * 4['Hi!', 'Hi!', 'Hi!', 'Hi!']重复
3 in [1, 2, 3]True元素是否存在于列表中

for x in [1, 2, 3]:

print x

1 2 3迭代

4.列表中的截取

使用切片进行截取

Python的列表截取与字符串操作类型,如下所示:

L = ['spam', 'Spam', 'SPAM!']
Python 表达式结果描述
L[2]'SPAM!'读取列表中第三个元素
L[-2]'Spam'读取列表中倒数第二个元素
L[1:]['Spam', 'SPAM!']从第二个元素开始截取列表

4.列表操作的函数以及方法

补充说明一下函数和方法的区别

首先摒弃错误认知:并不是类中的调用都叫方法

class Foo(object):
    def __init__(self):
        self.name="haiyan"
    def func(self):
        print(self.name)
#实例化
obj = Foo()
# 执行方式一:调用的func是方法
obj.func()#func 方法
# 执行方式二:调用的func是函数
Foo.func(obj)# 函数

例子中很明确,类对象调用func是方法,类调用func是函数,并且是自己传递参数123!

最大的区别是参数的传递参数,方法是自动传参self,函数是主动传参

那么以后我们就可以直接看参数是如何传递的来判断,

如果还不确定可以打印类型看看

from types import FunctionType,MethodType
print(isinstance(obj.func,MethodType))    ---># True
print(isinstance(Foo.func,FunctionType))  ---># True 

列表操作包含以下函数:
1、cmp(list1, list2):比较两个列表的元素 
2、len(list):列表元素个数 
3、max(list):返回列表元素最大值 
4、min(list):返回列表元素最小值 
5、list(seq):将元组转换为列表 

6、reversed(list):让我们能够实习反向迭代序列
7、sorted(list):返回一个有序列表,其中包含指定序列中的所有元素
列表操作包含以下方法:
1、list.append(obj):在列表末尾添加新的对象
2、list.count(obj):统计某个元素在列表中出现的次数
3、list.extend(seq):在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
4、list.index(obj):从列表中找出某个值第一个匹配项的索引位置
5、list.insert(index, obj):将对象插入列表
6、list.pop(obj=list[-1]):移除列表中的一个元素(默认最后一个元素),并且返回该元素的值pop(0)头元素。pop()最后一个元素
7、list.remove(obj):移除列表中某个值的第一个匹配项
8、list.reverse():反向列表中元素
9、list.sort([func]):对原列表进行排序

10、list.clear():就地清空列表的内容

11、list.copy():方法copy浅拷贝赋值列表。常规的复制(list2=list1)只是将另一个名称关联到列表,而这里会产生一个副本。如果要完全产生一个副本,则使用deepcopy(list)

deepcopy() 在二维以上的数据中体现的尤为明显(字典,二维及以上的数组)

 

三.元组

元组是固定且不可改变的。这意味着一旦元组被创建,和列表不同,它的内容无法被修改或它的大小也无法被改变。(优势)

t = (1, 2, 3, 4)
t[0] = 5    #非法,因为要修改元组的内容
#可以合并两个元组的内容
t1 = (1, 2, 3, 4)
t2 = (5, 6, 7, 8)
t1 + t2
(1, 2, 3, 4, 5, 6, 7, 8)
#如果只有一个值,需要在最后加一个逗号
t3=(42,)


#逗号是至关重要的
3*(40+2)
>>>126

3*(40+2,)
(42,42,42)
#可以使用tuple函数来将列表转为远足
tuple(t)
#如果我们需要获取元组的一部分元素使用切片
t[1:]

我们将其与列表的append操作比较,我们会看到它的复杂度是O(n)而不是列表的O(1)。这是因为对元组每添加一个新元素都会有分配和复制操作,而不是像列表那样仅在额外的空间耗尽时发生。所以元组并没有提供一个类似append的自增操作,任意两个元组相加始终返回一个新分配的元组。

元组的静态特性的另一个好处体现在一些会在Python后台发生的事情:资源缓存。

Python是一门垃圾收集语言,这意味着当一个变量不再被使用时,Python会将该变量使用的内存释放回操作系统,以供其他程序(变量)使用。然而,对于长度为1~20的元组,即使它们不在被使用,它们的空间也不会立刻还给系统,而是留待未来使用。这意味着当未来需要一个同样大小的新的元组时,我们不再需要向操作系统申请一块内存来存放数据,因为我们已经有了预留的空间。

这看上去可能是个细微的好处,但是实际上是元组一个很神奇的地方:它们可以被轻松快速地创建,因为它们可以避免跟操作系统频繁的打交道,而后者会花很长的时间。

下面举个例子会非常直观的说明问题
 

#列表的创建
%timeit l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
93.7 ns ± 3.33 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)


#元组的创建
%timeit t = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
18.5 ns ± 1.19 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

四.字典

在python中字dict和set是非常常用的两种数据结构,但是两种数据结构为什么要放在一起讨论。因为他们之所以拥有非常快的速度,是因为他们的内部结构都是散列表-哈希表(散列表其实是一个稀疏数组总是有空白元素的数组称为稀疏数组)

想要获取dict中的值,首先要知道key通过dict[key]获取对应的value,在散列表中为了达到这种操作,首先会计算key的hash值即散列值,把这个值最低的几位数字当作偏移量,在散列表里 
查找表元(具体取几位,得看当前散列表的大小)。若找到表元为空,异常KeyError,不为空,表元里会有一对 found_key:found_value。这时候 Python 会检验 search_key == found_key 是否为真,如果它们相等的话,就会返回 found_value。如果两个值不匹配,则是散列冲突。

键不可重复,而值是可以重复的

字典中的见是不可变的(元组),而value是可以进行修改的,可以是任何对象

dict的散列实现导致的结果
1.key必须是可hash的,所有不可变类型都是可哈希的故可作为键,可变类型不可哈希即不可作为键,如列表,字典类型。

2.在内存消耗上是巨大的,由于字典使用了散列表,而散列表又必须是稀疏的,这导致它在空间上的效率低下。

3.key查询很快,hash表空间换时间。

4.key的排列顺序,取决于添加顺序,并且当dict添加新数据,原有的排列可能会被打乱,因为Python 会设法保证大概还有三分之一的表元是空的,所以在快要达到这个阈值的时 
候,原有的散列表会被复制到一个更大的空间里面。这时候重新hash导致排列顺序改变。

5.由此可知,不要对字典同时进行迭代和修改。如果想扫描并修改一个字典,最好分成 
两步来进行:首先对字典迭代,以得出需要添加的内容,把这些内容放在一个新字典 
里;迭代结束之后再对原有字典进行更新

字典相关操作

1.创建字典

#创建空字典1
    
d = {}
print(d)

#创建空字典2
d = dict()

#直接赋值方式

d = {"one":1,"two":2,"three":3,"four":4}


#常规字典生成式

dd = {k:v for k,v in d.items()}
print(dd)

#加限制条件的字典生成方式

ddd = {k:v for k,v in d.items() if v % 2 ==0}
print(ddd)

2.字典删除元素

#访问字典中的数据
d = {"one":1,"two":2,"three":3,"four":4}
print(d["one"])

#变更字典里面的数据
d["one"] = "eins"
print(d)

#删除一个数据,使用del
del d["one"]
print(d)

#使用clear全部进行删除
d1=d.clear()

#使用pop()函数进行删除元素,在pop(key,'返回值')在pop中传入key值,如果没有放回默认值
d2=d.pop('one')

#使用popitem()随机删除一个元素
d3=d.popitem()

3.增加字典元素的方法

  • list['key'] = vaule

这种方法是通过字典的kye给字典添加元素,如果字典里已存在该key的值,则会覆盖,如果不存在,则会添加,如下如:

dic = {'name':'fuyong','age':29,'job':'none'}

dic['addr'] = 'henan'
print(dic)
#输出结果为:{'age': 29, 'addr': 'henan', 'name': 'fuyong', 'job': 'none'}
dic['addr'] = 'xinyang'
print(dic)
#输出结果为:{'age': 29, 'addr': 'xinyang', 'name': 'fuyong', 'job': 'none'}
  •  setdefault()方法:

此方法是根据函数对字典进行增添元素,参数为(‘key’,‘value’) value默认为none

与直接用 dict[key] = value 的添加元素方法不同,用setdefault(key,value)方法的时候,如果字典没有该key的时候,则会正常添加,如果以及有了该key,那么将不进行操作(不会覆盖原来的值)

dic = {'name':'fuyong','age':29,'job':'none'}
dic.setdefault('name','lixiang')
print(dic)  #结果不会改变: {'age': 29, 'name': 'fuyong', 'job': 'none'}

dic.setdefault('height')
print(dic)  #结果:{'age': 29, 'name': 'fuyong', 'height': None, 'job': 'none'}

dic.setdefault('addr','henan')
print(dic) #结果 {'addr': 'henan', 'age': 29, 'name': 'fuyong', 'height': None, 'job': 'none'}

4.修改字典中的元素

▷list['key'] = vaule

这种方法是通过字典的kye来修改对应的value值,如果字典里已存在该key的值,则会修改,如果不存在,则会重新添加

dic = {'name':'fuyong','age':29,'job':'none'}
 
dic['addr'] = 'henan'  #此时没有addr的key  则会添加
print(dic)
#输出结果为:{'age': 29, 'addr': 'henan', 'name': 'fuyong', 'job': 'none'}

dic['addr'] = 'xinyang' #此时以及有addr的key  则会修改
print(dic)
#输出结果为:{'age': 29, 'addr': 'xinyang', 'name': 'fuyong', 'job': 'none'}

▷update({key:value})方法:

该方法是用来追加、拓展原字典元素。

参数必须为一个字典,如下:

dic = {'name':'fuyong','age':29,'job':'none'}
dic.update({'addr':'henan'})
print(dic)      #结果为:{'job': 'none', 'addr': 'henan', 'age': 29, 'name': 'fuyong'}

如果传入的字典里有部分key与原字典相同,则该key所对应的值会被覆盖,其他没有的key则会被添加,如下:

dic = {'name':'fuyong','age':29,'job':'none'}
dic.update({'addr':'henan','name':'lixiang'})
print(dic)
#结果为:{'addr': 'henan', 'name': 'lixiang', 'job': 'none', 'age': 29}

5.查询字典中的元素

▷dic[key]

可以通过key来索引查询字典的元素,如果查不到,则会报错

dic = {'name':'fuyong','age':29,'job':'none'}
print(dic['name'])    #结果为:fuyong
print(dic['addr'])     #搜索不到,会报错。KeyError: 'addr'

▷get(key)方法:

该方法是用指定索引的方法来查找其所对应的元素,如果找不到,不会报错,可以通过 dic.get(key,'返回值') 方法指定找不到key时候的返回值,如下:

dic = {'name':'fuyong','age':29,'job':'none'}
print(dic.get('name'))  #结果为:fuyong
print(dic.get('addr'))  #结果为:none
print(dic.get('addr','找不到该数据')) #结果为:找不到该数据

字典中成员检测

d = {"one":1,"two":2,"three":3,"four":4}

if 2 in d:
    print("value")
    
if "two" in d:
    print("key")
    
if ("two",2) in d:
    print("kv")

使用for循环访问字典

 

d = {"one":1,"two":2,"three":3,"four":4}
#使用for循环,直接按key值访问

for k in d:
    print(k,d[k])
    
#上述代码也可以写成如下
    
for k in d.keys():
    print(k,d[k])

#只访问字典的值

for v in d.values():
    print(v)

#以下是特殊用法

for k,v in d.items():
    print(k,'--->',v)

字典相关函数

通用函数:len,max,min,dict

#默认是按照键值进行比较的
d = {"one":1,"two":2,"three":3,"four":4}
print(max(d))    #two
print(min(d))    #four
print(len(d))    #4
print(min(d.values())) #1

dict() 函数的使用方法:

dict0 = dict()  # 传一个空字典
print('dict0:', dict0)
 
dict1 = dict({'three': 3, 'four': 4})  # 传一个字典
print('dict1:', dict1)
 
dict2 = dict(five=5, six=6)  # 传关键字
print('dict2:', dict2)
 
dict3 = dict([('seven', 7), ('eight', 8)])  # 传一个包含一个或多个元祖的列表
print('dict3:', dict3)
 
dict5 = dict(zip(['eleven', 'twelve'], [11, 12]))  # 传一个zip()函数
print('dict5:', dict5)

str(字典):返回字典的字符串格式

d = {"one":1,"two":2,"three":3,"four":4}
print(str(d))
#这个时候str(d)中的每一个元素都变成了字符包括单引号,冒号,逗号

clear:清空字典

items:返回字典的键值对组成的元组格式

d = {"one":1,"two":2,"three":3,"four":4}

i = d.items()
print(type(i))
print(i)

d.clear()
print(d)

keys:返回字典的键组成的一个结构

d = {"one":1,"two":2,"three":3,"four":4}
k = d.keys()
print(type(k))
print(k)

values:返回字典的值组成的一个结构

d = {"one":1,"two":2,"three":3,"four":4}
v = d.values()
print(type(v))
print(v)

get:根据制定键返回相应的值,好处是可以设置默认值

d = {"one":1,"two":2,"three":3,"four":4}

print(d.get("one333"))    #返回None

#get默认值是None,可以设置
print(d.get("one",100))
print(d.get("one222",100))

fromkeys:使用指定的序列作为键,使用一个值作为字典的所有的键的值

p = ["one","two","three","four",]
#注意fromkeys两个参数的类型
#注意fromkeys的调用主体
d = dict.fromkeys(p,"222")
print(d)

pop:用于获取与指定键相关联的值,并将该键值对从字典删除

d = {"one":1,"two":2,"three":3,"four":4}

d.pop('one')   #获得1

#d变为了
d = {"two":2,"three":3,"four":4}

 

五.集合

集合中的散列表
集合的实现和dict一样,集合的元素就相当于dict中的key,只不过集合没有散列表指向的value。 
其特点: 
- 集合里的元素必须是可散列的 
- 集合很消耗内存 
- 可以很高效地判断元素是否存在于某个集合 
- 元素的次序取决于被添加到集合里的次序 
- 往集合里添加元素,可能会改变集合里已有元素的次序

  • 集合更接近数学上集合的概念。集合中每个元素都是无序的、不重复的任意对象。
  • 可以通过集合去判断数据的从属关系,也可以通过集合把数据结构中重复的元素减掉。集合可做集合运算,可添加和删除元素。
  • 集合内数据无序,即无法使用索引和分片
  • 集合内部数据元素具有唯一性,可以用来排除重复数据
  • 集合内的数据:str,int,float,tuple,冰冻集合等,即内部只能放置可哈希数据

集合的定义

#集合的定义,set()
s = set()
print(type(s))
print(s)

#也可以像下面这样做,大括号内一定要有值,否则定义出的将是一个dict
#为啥可以这样呢,就是前面我说的这相当于无值的字典
s = {1,2,3,4,5,6,7}
print(s)

创建集合时需要用list作为输入集合,可通过add()方法增加元素,remove()方法删除元素

#从列表中创建集合
s = set([1,2,3])

#使用add进行元素的添加
s.add(6)

#使用update进行多个元素的添加,update方法中参数需要传入可迭代的对象
s.update([4,5,6])

#使用remove进行删除
s.remove(2)

#可以使用discard来进行删除
s.discard(4)

#discard和remove区别
#使用discard和remove都可以删除set当中的元素,区别就是remove的元素在set当中没有的话会报错,而discard不会

 

集合的内涵

普通集合内涵(用来过滤)
--------以下集合会在初始化后自动过滤掉重复元素

#普通集合内涵
s = {33,1,33,6,9,126,8,6,3,77,88,99,126}
print(s)

#普通循环集合内涵
ss = {i for i in s}
print(ss)

#带条件的集合内涵
sss = {i for i in s if i % 2 ==0}
print(sss)

#多循环集合的内涵
s1 = {1,2,3,4}
s2 = {"nice","to","meet","you"}

s3 = {m*n for m in s2 for n in s1}
print(s3)



 ----集合函数 

  •  intersection:交集
  • difference:差集
  • union:并集
  • issubset:检查一个集合是否为另一个子集
  • issuperset:检查一个集合是否为另一个超集 

 代码来测试一波

s1 = {1,2,3,4,5,6,7}
s2 = {5,6,7,8,9}

#交集
s_1 = s1.intersection(s2)
print("交集:",s_1)

#差集
s_2 = s1.difference(s2)
print("差集:",s_2)

#并集
s_3 = s1.union(s2)
print("并集:",s_3)

#检查一个集合是否为另一个子集
s_4 = s1.issubset(s2)
print("检查子集结果:",s_4)

#检查一个集合是否为另一个超集
s_5 = s1.issuperset(s2)
print("检查超集结果:",s_5)
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值