python数据结构

目录

一、列表

二、元组

三、字典dict

四、集合

五、迭代器

六、生成器Generator

四、简单列表习题练习


一、列表

列表List(用 [ ] 标识)是Python 中使用最频繁的数据类型。可以完成大多数集合类的数据结构实现,支持字符,数字,字符串甚至可以包含列表(即嵌套)。下标为空表示取到头或尾。

列表和元组的区别:

  • 元组不可变:只能读元素,不可修改
  • 列表可变:可读可写

1)创建列表:先创建空列表实例,再添加元素

python中不限制列表中元素的类型(元素可存放任意类型)

a = []  #空列表  实例化
b = list()    #实例化
c = ["hello","python",1]

a.append("python")   #添加元素
b.append("hello")  #添加元素
print(type(a))  #<class 'list'>
print(type(b))  #<class 'list'>
print(type(c))  #<class 'list'>

2) 访问下标:注意防止下标越界。

打印列表最后一个元素:-1指的是最后一个元素(长度-1)

print(list[len(list)-1])  #打印列表list最后一个元素
print(list[-1])    #打印列表list最后一个元素

3)切片操作

取出列表中下标连续的一组元素,也相当于得到一个子列表(下标范围前闭后开)

除了获取某个确定下标的元素外,切片操作得到的是列表形式的数据

list = ['runoob', 786 , 2.23, 'john', 70.2]
tinylist = [123, 'john']
  
print(list)               # 输出完整列表  ['runoob', 786 , 2.23, 'john', 70.2]
print(list[0])            # 输出列表的第一个元素   runoob
print(list[:-1])          #从前往后取数据,不包括最后一个元素
print(list[:])            #得到列表自身所有数据
print(list[1:3])          # 输出第二个至第三个元素  [786 , 2.23] 
print(list[2:])           # 输出从第三个开始至列表末尾的所有元素   [2.23, 'john', 70.2]
print(tinylist * 2)       # 输出列表两次 [123, 'john', 123, 'john']
print(list + tinylist)    # 打印组合的列表  ['runoob', 786 , 2.23, 'john', 70.2,123, 'john']

切片操作,可以指定步长(步长为负数时,从后往前取数据):

list = [1,2,3,4,5,6,7,8]
print(list[::1])  #1是指定的步长   [1, 2, 3, 4, 5, 6, 7, 8]
print(list[1:7:2])  #2 是指定的步长    [2, 4, 6]

print(list[::-2])  #2 是指定的步长  [8, 6, 4, 2]
print(list[::-1])  #2 是指定的步长  [8, 7, 6, 5, 4, 3, 2, 1]

4)列表的遍历

取出列表中的每个元素,并进行某种操作

list = [1,2,3,4,5,6,7,8,9]
#方法一:
for elem in list:
    print(elem)
    elem = elem + 10  #不修改变量本身,只修改临时变量
    print(elem)

#方法2:
for i in range(0,len(list)):
    print(list[i])
    list[i] = list[i]+10  #可修改每一个列表元素    
print(list)  #输出新的list

#方法3:使用while循环,通过下标遍历
i = 0
while 1 < len(list):
    print(list[i])
    i += 1

5)列表的新增(插入元素)

list列表可插入不同数据类型的元素,且append函数是搭配列表对象一起使用的。需要搭配对象使用的函数也叫“方法”

append:把元素插在列表最后

insert:插入到指定位置

expend:把新列表拼接到旧列表后面

list = [1,2,3,4,5]
list.append(0)
list.append('hello')
print(list)   #[1, 2, 3, 4, 5, 0, 'hello']

list1 = ["hello","python"]
print(list.expend(list1)) #输出[1,2,3,4,5,"hello","python"]
print(list1.expend(list))  #输出["hello","python",1,2,3,4,5]

insert插入方法(指定下标处插入元素):

6)列表的修改:使用下标直接替换

a = ["1","2","python"]
a[0] = "hello"
print(a)  #输出["hello","2","python"]

6)列表的查找

注意!!!索引不能超出列表长度

list = [1,2,3,4,5]
print(len(list))   #求列表长度:5
print(5 in list)   #判断某个元素5是否存在于列表里
print(list.index(5))  #使用index获取元素5在列表中的位置
print(list.count(5))   #统计元素5出现的次数

7)列表的删除

  • pop():删除末尾元素
  • pop(i):删除i下标的元素
  • remove(num): 删除列表中的num元素
  • clear():清空元素,返回空列表

删除末位几个数据,连续几次pop操作即可

list = [1,2,3,4,5] 
list.pop()  #删除末尾元素  #[1, 2, 3, 4]
list.pop(2)  #删除下标为2的元素   [1, 2, 4]
list.remove(4)   #[1, 2]
print(list)      #[1, 2]

company = input().split()
companylist = []
for i in company:
    companylist.append(i)

#方法一
companylist.pop(0)  #删除第一个元素
print(companylist)
#方法二
companylist.remove(companylist[0])
print(companylist)

给定两个字符串A和·B,删除A字符串中的B字符串:

friend = input().split()
argfriend = input()

friendlist = []
for i in friend:
    friendlist.append(i)
friendlist.remove(argfriend)
print(friendlist)

8)列表的反转reverse和排序:

注意!!!列表反转reverse()和排序sort()不能直接和print放一起使用(如:print(num.sort())写法错误),分开两行才行,如下代码:

list = [1,9,7,100,2,3,4,5]
list.reverse()
print(list)    # [5, 4, 3, 2, 100, 7, 9, 1]
list.sort()
print(list)    #  [1, 2, 3, 4, 5, 7, 9, 100]

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

  • 使用 + 拼接两个列表,不改变原列表
  • 使用extend拼接(不需要变量会接收,没有返回值),相比“+”拼接更高效(把后一个列表拼接到前一个列表里),会改变原列表a的内容(拼接后是存储到新的变量a里,同时也会释放旧的变量a)
a = [1,2,3]
b = [6,7,8]
print(a + b)   #[1, 2, 3, 6, 7, 8]  

# c = a.extend(b)   # 返回None,extend拼接不需要返回值
a.extend(b)   #把b拼接到a列表里
print(a)   #[1, 2, 3, 6, 7, 8]
print(b)   #[6, 7, 8]

二、元组

元组中的元素值不允许删除,但可使用del语句来删除整个元组:del tup

元组之间可以使用 + 号和 * 号进行运算。可以组合和复制,运算后会生成一个新的元组。

元组不可变对象,相当于只读列表(不能修改)但是可以哈希

元组中只包含一个元素时,需要在元素后面添加逗号,如: tup1 = (50,)

83060360d86b45a99ac69ba56ec19b7f.png

1)创建元组:

元组(用 () 标识),元素可为任意类型。

a = ()  #创建一个空元组
b = tuple()  #创建一个空元组
print(type(a))
print(type(b))

c = (1,2,'python',[1,2,3],[],True)
print(c)     #(1, 2, 'python', [1, 2, 3], [], True)
print(type(c))   #<class 'tuple'>

2)元组访问:通过下标获取特定元素或者切片获取元组的某一部分

注意不能数组越界

c = (1,2,'python',[1,2,3],[],True)
print(c[1])  #2
print(c[-1])   #True
print(c[0:4])   #(1, 2, 'python', [1, 2, 3])

#for循环遍历:
for elem in c:
    print(elem)

#判定元素是否存在:

print(2 in c)  #判断元素2是否存在元组中

print(c.index(2))  #打印输出下标为2的元素

因为元组不可变,故不能进行修改、删除、新增操作,只能查看

3)元组与列表的转换

a = [1,2,3,4]
b = tuple(a)  #列表a转化为元组b

c = (1,2,3,4)
d = list(a)  #元组c转化为列表d

三、字典dict

字典("{ }"标识),是除列表以外最灵活的内置的键值(key-value)对组合而成的数据结构类型是一种可变容器模型。

  • 键:唯一不可变的(可哈希的值):如字符串,数字或元组。
  • 值:可以取任何数据类型,字典的操作都是围绕key展开的。

1)创建字典 (最后一个键值对后的逗号可有可无)

#创建字典
a = {}
b = dict()

#字典初始化:
a = {"id":1,"name":"张三","性别":"男"}

dict = {    #推荐写法,可读性更高
    "id":1,
    "name":"张三",
    "性别":"男"
}

2) 查找key

  •  in或者下标的形式[],两种方法都很高效(字典背后使用了哈希表)

对于列表list使用in查找是比较低效的(需要遍历),使用[ ]下标索引高效

dict = {    #推荐写法,可读性更高
    "id":1,
    "name":"张三",
    "性别":"男"
}

#判断键和值是否在字典里
print("id" in dict)   #True 
print("name" in dict)   #True 

#判断键和值不在字典里
print("id" not in dict)   #False 
print("python" not in dict)   #True 

#根据key查找对应的value
print(dict["id"])   #1
print(dict["性别"])   #男
dict = {}
dict['one'] = "This is one"
dict[2] = "This is two"
 
tinydict = {'name': 'runoob','code':6734, 'dept': 'sales'}
 
print dict['one']          # 输出键为'one' 的值  This is one
print dict[2]              # 输出键为 2 的值  This is two
print tinydict             # 输出完整的字典   {'name': 'runoob','code':6734, 'dept': 'sales'}
print tinydict.keys()      # 输出所有键  ['dept', 'code', 'name']
print tinydict.values()    # 输出所有值  ['sales', 6734, 'runoob']

3)字典的新增(写、修改)

dict["socre"] = 98
dict["班级"] = "S201" 
print(dict)    # {'id': 1, 'name': '张三', '性别': '男', 'socre': 98, '班级': 'S201'}

#若key是已经存在的,再次写入即修改
dict["socre"] = 90
print(dict)   #{'id': 1, 'name': '张三', '性别': '男', 'socre': 90, '班级': 'S201'}

4)字典的删除(单一键值对的删除del和pop、和清空字典clear)

tinydict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}
 
tinydict.pop('Name')
del tinydict['Name']  # 删除键是'Name'的条目
tinydict.clear()      # 清空字典所有条目,只保留空字典{}
del tinydict          # 删除整个字典 ,字典变量不存在了

5)字典的遍历(字典的设计初衷不是遍历,而是增删查改),哈希表能以“常数级”时间复杂度完成增删查改。注意!!Java和C++中插入元素顺序,不代表打印顺序(哈希表是无序的),python中做了特殊处理,是有序的。

for key in dict:
    print(key,dict[key])  #根据key打印对应的值


print(dict.keys())   #dict_keys(['id', 'name', '性别', 'socre', '班级'])
print(dict.values())   #dict_values([1, '张三', '男', 90, 'S201'])
print(dict.items())    #dict_items([('id', 1), ('name', '张三'), ('性别', '男'), ('socre', 90), ('班级', 'S201')])

for key ,value in dict.items():
    print(key,value)

6)字典中合法key的类型

使用哈希函数hash能够计算一个变量的哈希值

#可哈希的对象:(不可变对象)
print(hash(0))   #0
print(hash(3.14))   #322818021289917443
print(hash(True))   #1
print(hash("hello"))   #604443049439005304
print(hash((1,2,3)))  #2528502973977326415

#不可哈希:列表、字典(因为他们是可变的)

字典、列表、元组是python中常用的内置函数,相比于其他类型(int  str  float)他们的内部可以包含其他元素

列表是有序的对象集合,字典是无序的对象集合。字典中的元素是通过键来存取(键值对key-value),而不是通过偏移存取。


四、集合

集合 set,它是一个无序不重复元素序列

1)集合的创建

a = {"xiaomi","huawei","oppo","vivo"}
print(a)   #

b = set()  #空集合

2)添加元素

  • add():添加元素
  • update():可接集合,列表,元组,字典等。

b = set()  #空集合
b.add("apple")
a.add("banana")
print(b)

3)合并去重:union函数或者( | 操作符)

a_set= {"apple","huawei","xiaomi"}
b_set = {"apple","oppo"}

a_set.union(b_set)    #set(["apple","huawei","xiaomi","oppo"])

4)求差集\不重合度:difference、symmetric_difference找出存在集合 A 但是不存在 集合 B 的元素(- 操作符)

aset = {"Apple", "Huawei"}
bset = {"Xiaomi", "Huawei"}
aset.difference(bset)    #set(['Apple'])
aset.symmetric_difference(bset)   ##set(['Apple',Xiaomi])

5)集合判断

  • 元素是否在集合中:in
  • 两个集合是否有相同元素:isdisjoint():有相同元素返回False,没有返回True
  • 是否有子集:issubset()
aset = {"Apple", "Huawei"}
print("Apple" in aset)    #True

五、迭代器

可迭代对象:可以利用 for 循环的对象,如列表、元组、字典、字符串

判断是否可迭代:isinstance(),需要先导入Python 内置的collections.abc模块,其中Iterable是类

from collections.abc import Iterable

isinstance([0, 1, 2], Iterable) # 列表  True
isinstance({"name": "王炳明"}, Iterable) # 字典  True
isinstance((1,2,3), Iterable) # 元组  True
isinstance("hello", Iterable) # 字符串  True

可迭代协议:

1)第一种场景:如果一个对象内部实现了 __iter__() 方法 ,并返回一个迭代器实例,那么该对象就是可迭代对象

class Array:
    mylist = [0,1,2]

    def __iter__(self):  # 返回迭代器类的实例
        return iter(self.mylist)

my_list = Array()  # 得到可迭代对象
print(isinstance(my_list, Iterable)) # True

for i in my_list:
    print(i)

2)第二种场景:假设一个对象没有实现 __iter__() ,Python 解释器 __getitem__() 方法获取元素,如果可行,那么该对象也是一个可迭代对象。

from collections.abc import Iterable

class Array:
    mylist = [0,1,2]

    def __getitem__(self, item):
        return self.mylist[item]

my_list = Array()  # 得到一个可迭代对象
print(isinstance(my_list, Iterable)) # False

for i in my_list:
    print(i)

什么是迭代器?

当你对一个可迭代对象使用 iter 函数后,它会返回一个迭代器对象,对于迭代器对象,我们可以使用 next 函数,去获取元素,每执行一次,获取一次,等到全部获取完毕,会抛出 StopIteration 提示无元素可取。

alist = [0, 1, 2, 3]   #列表
gen = iter(alist)   #对可迭代对象 列表 使用iter函数,并返回一个迭代器对象gen

next(gen)  #获取迭代器中的个元素 0
next(gen)  #1
next(gen)  #2
next(gen)  #3
next(gen)  #没有对象了,抛出错误StopIteration

迭代器协议:

相比可迭代对象(list tuple dict str),迭代器内部多了一个函数_next_()

迭代器是在可迭代基础上实现的,创建一个迭代器,得先有一个可迭代对象。

如何创建一个可迭代对象?并以可迭代对象为基础创建一个迭代器?

from collections.abc import Iterator

class Array:
    index = 0
    mylist = [0,1,2]  #可迭代对象:列表

    # 返回该对象的迭代器类的实例
    # 因为自己就是迭代器,所以返回self
    def __iter__(self):
        return self

    # 当无元素时,必要抛出 StopIteration
    def __next__(self):
        if self.index <= len(self.mylist)-1:
            value = self.mylist[self.index]
            self.index += 1
            return value
        raise StopIteration

my_iterator = iter(Array())
print(isinstance(my_iterator, Iterator)) # output: True
print(next(my_iterator))  # output: 0
print(next(my_iterator))  # output: 1
print(next(my_iterator))  # output: 2
print(next(my_iterator))  # StopIteration

六、生成器Generator

像迭代器那样使用for循环来获取元素的函数,实现了延时计算,缓解了在大量数据下内存消耗过大的问题。当把 [] 换成 () ,返回的就不是列表了,而是一个生成器

gen = (i for i in range(5))
print(gen)   #输出<generator object <genexpr> at 0x000001D0413D4F10>  表明是一个生成器对象

mylist = [i for i in range(5)]
print(mylist)   #输出[0, 1, 2, 3, 4]  返回列表而非生成器

yield:相当于函数里的 return,但 又有所不同。

  • 当一个函数运行到 yield 后,函数的运行会暂停,并且会把 yield 后的值返回出去。

  • 若 yield 没有接任何值,则返回 None

  • yield 虽然返回了,但是函数并没有结束

def generator_factory(top=5):
     index = 0
     while index < top:
         print("index 值为: " + str(index))
         index = index + 1
         yield index
     raise StopIteration

gen = generator_factory()
print(gen)# 此时gen是生成器对象

1)生成器的使用:从生成器对象中取出元素

第一种方法:使用 next 方法一个一个地把元素取出来,如果元素全部取完了,生成器会抛出 StopIteration 的异常。

gen = (i for i in range(3))
print(gen)   #输出<generator object <genexpr> at 0x000001D0413D4F10>  表明是一个生成器对象
next(gen)  #0
next(gen)   #1
next(gen)   #2
next(gen)  #  取完了报错  StopIteration

 第二种方法:使用 for 循环一个一个地迭代出来

gen = (i for i in range(3))
for i in gen:
    print(i)

2)生成器的激活

生成器的生命周期,有四个状态:

  • GEN_CREATED :生成器已创建,还未被激活
  • GEN_RUNNING:解释器正在执行(只有在多线程应用中才能看到这个状态)
  • GEN_SUSPENDED : 在 yield 表达式处暂停
  • GEN_CLOSED:生成器执行结束
from inspect import getgeneratorstate

gen = (i for i in range(2))
print(getgeneratorstate(gen))   #GEN_CREATED生成器已创建,还未被激活

next(gen)
print(getgeneratorstate(gen))    #GEN_SUSPENDED  在 yield 表达式处暂停
next(gen)
print(getgeneratorstate(gen))    #GEN_SUSPENDED  在 yield 表达式处暂停
next(gen)   #元素取完了,报错StopIteration

3)生成器异常:元素取完了就会抛出异常

最开始先定义一个函数

def generator_func(top=2):   #定义一个生成器函数
    index = 0
    while index < top:
        index = index + 1
        yield index
    raise StopIteration   #没有元素返回时,抛出 StopIteration 异常,为了满足生成器的协议。

  四、简单列表习题练习

(1)列表的拆分(对输入数据划分)

a = input().split()    #split()函数为使用空格拆分字符串 ,
print(a)  
#输入:NiuNiu NiuMei NiuNeng 
#输出:['NiuNiu', 'NiuMei', 'NiuNeng']

 (2)数字列表生成

输入数字字符串,将其转化为列表输出

#方法一·:
a = input().split()  #分割字符串
b = []  #创建一个空列表
for i in a:     #遍历输入字符串
    b.append(int(i))  #将每次遍历获取到的元素添加到列表
print(b)  #打印列表
    
#方法二:
print([int(i) for i in input().split()])   #利用列表解析快速创建列表
#-------------------------------------------------------------------------
#将输入字符串转化为列表,再在列表后添加元素
Name = input().split()
listName = []
for i in Name:  #在输入中遍历
    listName.append(i)   #将每个字符串添加到列表

#在末尾添加元素
listName.append('Allen')
print(listName)

#在指定位置添加元素
listName.insert(0,'Allen')
print(listName)

(3)列表排序

  • sorted()只是临时排序,不会改变原来的列表
  • sort()会改变原来的列表,同时添加参数reverse可反转列表
my_list = ['P','y','t','h','o','n']

print(sorted(my_list))   #输出排序列表:['P', 'h', 'n', 'o', 't', 'y']
print(my_list)   #输出源列表,因为sorted不改变源列表['P','y','t','h','o','n']
my_list.sort(reverse=True)  #源列表反转
print(my_list)   #输出原列表反转后的列表['y', 't', 'o', 'n', 'h', 'P']

(4)密码游戏:

输入一个四位数字,通过位置的交换和对应位置数字的改变,输出四位整数:

#方法一:
num = input()
b = []  
for i in num:
    a = int(i)
    a = (a + 3) % 9   #改变数字
    b.append(a) 

c = b[2]*1000 + b[3]*100 + b[0]*10 + b[1]   #数字交换
print('{:0>4}'.format(c))   #输出四位数字

#方法二:
num1=input()
num1=list(num1)

a=[]
for i in range(0,4):
    x=str((int(num1[i])+3)%9)
    a.append(x)
x=a[0]
a[0]=a[2]
a[2]=x
y=a[1]
a[1]=a[3]
a[3]=y
print(''.join(a))

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值