22.列表

列表的创建

  1. 列表相当于其他编程语言中的数组.属于容器类的数据类型。
  2. 它有两种创建方式:
    1. 使用中括号[]
    2. 使用list()
    #1.创建列表对象的第一种方式:使用中括号
    #list = ["Hello",45,67.4,"World"]
    #2.创建列表的第二种方式:使用list()
    list = list(["Hello",45,67.4,"World"])
    print(id(list))     #1551289858880
    print(type(list))   #<class 'list'>
    print(list)         #['Hello', 45, 67.4, 'World']
    

列表的特点:

  1. 列表元素按照顺序有序存储
  2. 索引映射唯一一个数据(如果索引从右往左则从-1到-N;如果索引从左往右则从0到N-1)
  3. 列表可以存储重复数据
  4. 任意数据类型混存
  5. 根据需要动态分配和回收内存

列表的查询操作

  1. 获取列表中指定元素的索引:index()方法
lst = ['hello','world']
print(lst.index('world'))   #1
  1. 获取列表中的单个元素:类似数组一样,arr[i]
  2. 获取列表中的多个元素
  3. 判断指定元素在列表是否存在:in和not in的使用
  4. 列表元素的遍历:for-in循环

列表元素的增加

  1. append():在列表的末尾增加一个元素
  2. extend():在列表的末尾至少添加一个元素
  3. insert():在列表的任意位置添加一个元素
  4. 切片:在列表的任意位置添加至少一个元素.列表是有序的,可以切片,方便取值
lst = [10,35]
print(lst) #list[10, 35]
lst.append(67)
print(lst)  #[10, 35, 67]

lst1 = ["Hello"]
lst.append(lst1)   #[10, 35, 67, ['Hello']]
#lst.extend(lst1)  #[10, 35, 67, 'Hello']
print(lst)

#在任意位置上添加一个元素
lst.insert(1,"Hello")
print(lst)  #[10, 'Hello', 35, 67, 'Hello']
#在任意位置上添加N多个元素(切片操作)
lst[1:5:1] = lst1   #start为1,stop为5,step为1
print(lst)  #[10, 'Hello']

列表元素的删除

  1. remove():通过元素删除列表中该元素
  2. pop():通过索引删除列表中对应的元素,该方法有返回值,返回值为删除的元素
  3. 切片,删除至少一个元素,但是会产生一个新的列表对象
new_lst = lst[1:3]
print("切片前:",lst,id(lst))           #切片前: [20, 30, 40] 2056922381056
print("切片后:",new_lst,id(new_lst))   #切片后: [30, 40] 2056922067392

#不产生新的列表对象,而是删除原列表中的内容
lst[1:3] = []
print(lst)      #[20]
  1. clear():清空列表
  2. del():按照索引删除该元素

列表元素的修改

  1. 为指定索引的元素赋予一个新值
  2. 为指定的切片赋予一个新值
lst = [10,20,30]
lst[0] = 100
print(lst)  #[100, 20, 30]

lst[1:3] = [200,300,400,500]     
print(lst)  #[100, 200, 300, 400, 500]  

列表元素的排序操作

  1. 方法sort(),不会产生新的列表对象
  2. 内置函数 sorted(),会产生新的列表对象
lst = [34,21,46,78,11,22,99]
#sort方法
#1.升序排序
print("排序前:",lst)   #排序前: [34, 21, 46, 78, 11, 22, 99]
lst.sort()
print("排序后:",lst)   #排序后: [11, 21, 22, 34, 46, 78, 99]
#2.降序排序
lst.sort(reverse = True)#reverse等于true表示降序,等于false表示升序
print("排序后:",lst)   #排序后: [99, 78, 46, 34, 22, 21, 11]

#内置函数sorted()1.升序排序
lst = [34,21,46,78,11,22,99]
new_lst = sorted(lst)
new_lst1 = sorted(lst,reverse=True)
print(lst)      #[34, 21, 46, 78, 11, 22, 99]
print(new_lst)  #[11, 21, 22, 34, 46, 78, 99]
print(new_lst1) #[99, 78, 46, 34, 22, 21, 11]

列表的其他常用方法:

  1. count():统计某个元素在列表中出现的次数
  2. index():从列表中找出某个元素第一个匹配成功时的索引位置
  3. reverse():将列表中的元素反向存放
l = [100,200,'hello',100,'world']
print(l.count(100))     #2
print(l.index('hello')) #2

l.reverse()
print(l)    #['world', 100, 'hello', 200, 100]

列表生成式(列表推导式):简称生成列表的公式

l1 = [i for i in range(1,5)]
print(l1)  # [1, 2, 3, 4]

23.字典

它以键值对的方式存储数据,字典是一个无序的序列,底层使用散列表

字典的特点:

  1. 字典中的所有元素都是一个键值对,key不允许重复,value可以重复。
  2. 字典中的元素是无序的
  3. 字典中的key必须是不可变对象,如元组,字符串,整型,布尔型,不能是列表,字典,集合

字典的创建

  1. 使用花括号
  2. 使用内置函数dict()
#第一种创建字典的方式:使用花括号
stu1 = { 'num' : 20170201818,'scores':98.5,'name':'李四'}
print(stu1)         #{'num': 20170201818, 'scores': 98.5, 'name': '李四'}
print(type(stu1))   #<class 'dict'>,字典类型
#第二种创建字典的方式:使用dict()
stu2 = dict(name = '张三')
print(stu2)         #{'name': '张三'}

dic = dict((('one', 1),('two', 2),('three', 3)))
# dic = dict([('one', 1),('two', 2),('three', 3)])
print(dic)  # {'one': 1, 'two': 2, 'three': 3}

#创建一个空字典
stu3 = {}
print(stu3)         #{}

字典中元素的获取

  1. 使用[]获取元素
  2. 使用get()方法
    1和2的区别:对于1,如果字典中不存在指定的key,则抛出keyerror异常.对于2,如果字典中不存在指定的key,返回none,可以通过参数设置默认的value,当指定的key不存在时返回
stu1 = { 'num' : 20170201818,'scores':98.5,'name':'李四'}
print(stu1['name'])     #李四
print(stu1.get('name')) #李四
#get方法,如果字典中不存在指定的key,返回none,可以通过参数设置默认的value,当指定的key不存在时返回
print(stu1.get('张三','您查找的人不在')) #您查找的人不在

key的判断

  1. in,not in判断指定的key是否在字典中存在

字典元素的删除

  1. 通过键删除键值对:del 字典名['key']
  2. popitem():删除最后一个键值对
  3. pop 通过key删除字典的键值对,有返回值,可设置返回值
dic = {'name':'Jack','age':23}
ret = dic.pop('height','您查询的栏目不存在!')    
#您查询的栏目不存在!
print(ret)

ret = dic.pop('name')
print(ret)  #Jack
print(dic)  #{'age': 23}

字典元素的新增

# 通过键值对直接增加
dic = {'name': 'Kate', 'age': 18}
dic['weight'] = 75 # 没有weight这个键,就增加键值对
print(dic) # {'name': 'Kate', 'age': 18, 'weight': 75}
dic['name'] = 'barry' # 有name这个键,就成了字典的改值
print(dic) # {'name': 'barry', 'age': 18, 'weight': 75}

# setdefault函数
dic = {'name': 'Kate', 'age': 18}
dic.setdefault('height',175) # 没有height此键,则添加
print(dic) # {'name': 'Kate', 'age': 18, 'height': 175}
dic.setdefault('name','barry') # 有此键则不变
print(dic) # {'name': 'Kate', 'age': 18, 'height': 175}
#它有返回值
dic = {'name': 'Kate', 'age': 18}
ret = dic.setdefault('name')
print(ret)  # Kate

获取字典视图的三个方法

  1. keys():获取字典中的所有键,得到的高仿列表可以转化成列表
stu1 = { 'num' : 20170201818,'scores':98.5,'name':'李四'}
key = stu1.keys()
print(key)          #dict_keys(['num', 'scores', 'name'])
print(type(key))    #<class 'dict_keys'>
#将所有的key组成的视图转成列表
print(list(key))    #['num', 'scores', 'name']
  1. values():获取字典中的所有值,得到的高仿列表可以转化成列表
  2. items():获取字典中的所有键值对,得到的高仿列表可以转化成列表

字典元素的遍历:for-in循环

stu1 = { 'num' : 20170201818,'scores':98.5,'name':'李四'}
for item in stu1:

    print(item,stu1[item],stu1.get(item))
#num 20170201818 20170201818
#scores 98.5 98.5
#name 李四 李四
for i,j in stu1.items():
    print(i,j)
#num 20170201818
#scores 98.5
#name 李四

fromkeys()方法:创建一个字典:字典的所有键来自一个可迭代对象,字典的值使用同一个值。

dic = dict.fromkeys([1, 2, 3], [])
print(dic)  #{1: [], 2: [], 3: []}
dic[3].append(666)
print(id(dic[1]),id(dic[2]),id(dic[3]))#三者相同
#通过fromkeys得到的字典的值为可变的数据类型,值共用一个
print(dic)  # {1: [666], 2: [666], 3: [666]}

遍历字典的过程中,改变字典大小的问题:
先看一个小例子:删除键中含有'k'的键值对

dic = {'k1':'Jack','k2':'barry','k3': 'Kate', 'age': 18}
for i in dic:
    if 'k' in i:
        del dic[i]
print(dic)

结果报错:RuntimeError: dictionary changed size during iteration所以,在循环一个字典的过程中,不要改变字典的大小(增,删字典的元素),这样会直接报错。
改正如下:

dic = {'k1':'Jack','k2':'barry','k3': 'Kate', 'age': 18}

#既然不能再遍历字典的过程中删除字典元素,那么就改变为:对由键组成的列表
#进行遍历
for key in list(dic.keys()):
    if 'k' in key:
        dic.pop(key)
        # del dic[key]
print(dic)  #{'age': 18}

字典生成式

zip():用于将可迭代的对象作为参数,将对象中对应的参数打包成一个元组,然后返回由这些元组组成的列表

ret = list(zip('abcdefg', range(3), range(4)))
# [('a', 0, 0), ('b', 1, 1), ('c', 2, 2)]
print(ret)

items = ['hello','world','python']
label = [100,200,300]
d = {item.upper():price for item,price in zip(items,label)}
print(d)        #{'HELLO': 100, 'WORLD': 200, 'PYTHON': 300}

24.元组

python内置的数据结构之一,是一个不可变序列,又称只读列表。不可变序列有字符串,元组,没有对元组元素增删改的操作,也可以切片;可变序列有列表,字典,集合。有增删改的操作,对象地址不发生更改这种容器类的数据类型存放重要的数据,属于元组的元素不能更改.在Python3.5版本(包括此版本)之前,字典是无序的.在Python3.6版本之后,字典会按照初建字典时的顺序排列(即第一次插入数据的顺序排序)。

元组的创建方式

  1. 直接使用小括号()
  2. 使用内置函数tuple()
t1 = ('Hello','world','python')
#创建元组的第一种方式:使用圆括号
print(t1)       #('Hello', 'world', 'python')
print(type(t1)) #<class 'tuple'>
#创建元组的第二种方式:使用内置函数tuple()
t2 = tuple(('Hello','world','python'))
print(t2)       #('Hello', 'world', 'python')
#对于创建一个元素的元组,需要使用逗号和圆括号,这是为了与string类型区分
t3 = ('Hello',)
print(t3)
print(type(t3))     #<class 'tuple'>
str = ('Hello')
print(type(str))    #<class 'str'>

#元组可以用于交换两个变量的值
a,b = 100,200
a,b = (b,a)
print(a,b)  #200 100

元组的遍历
元组是可迭代对象,所以可以使用for-in循环。可迭代对象:定义了__iter__方法的类定义的对象

print('__iter__' in dir(tuple)) # True,表示元组是一种可迭代对象

t = ('Hello','World','Pyhton')
for item in t:
    print(item)

元组的常用方法:

  1. index():通过元素找索引(可切片),找到第一个元素就返回,找不到该元素即报错
  2. count():获取某元素在元组中出现的次数

25.集合

集合是没有value的字典,与列表,字典一样都是可变类型的序列

集合的创建方式

  1. 使用{}
  2. 使用内置函数set()
#集合的创建方式
s = {'Hello','World','Python'}
print(s,type(s))                        #{'World', 'Python', 'Hello'} <class 'set'>
#将列表中的元素转成集合
s1 = set(['Hello','World','Python'])
print(s1,type(s1))                      #{'Python', 'Hello', 'World'} <class 'set'>

#将元组中的元素转成集合
s2 = set((1,2,3,45,65))
print(s2,type(s2))                      #{65, 1, 2, 3, 45} <class 'set'>
#创建一个空集合
s3 = set()
print(s3,type(s3))                      #set() <class 'set'>
#这样创建的是一个空字典
s4 = {}
print(s4,type(s4))                      #{} <class 'dict'>

集合元素的判断操作:使用in和not in

集合元素的新增操作

  1. add():一次添加一个元素
  2. update():一次添加至少一个元素,迭代着增加。
s1 = {"Hello",'World'}
s1.add(100)
print(s1,type(s1))  #{100, 'Hello', 'World'} <class 'set'>
s1.update({'Python',200,300})
print(s1,type(s1))  #{'World', 'Python', 100, 'Hello', 200, 300} <class 'set'>

集合的删除操作

  1. remove()方法:一次删除一个指定元素,如果指定的元素不存在抛出KeyError
  2. discard()方法:一次删除一个指定元素,如果指定的元素不存在不抛出异常
  3. pop()方法:一次删除一个任意元素
  4. clear()方法:清空集合

集合间的关系

  1. 相等:可以使用运算符==或者!=来判断
  2. 子集:可以使用方法issubset()来判断
  3. 超集:可以使用方法issuperset来判断。超集的概念和子集相反
  4. 交集:可以使用方法isdisjoint()来判断两个集合是否没有交集

集合的数学操作

#1.交集:intersection()和&等价都是交集操作
s1 = {10,30}
s2 = {10,20}
print(s1.intersection(s2))  #10
print(s1 & s2)              #10

#2.并集操作:union和|等价,都是并集操作
print(s1.union(s2))     #{10, 20, 30}
print(s1 | s2)          #{10, 20, 30}

#3.差集操作:difference()方法和-等价
print(s1.difference(s2))#{30}
print(s1 - s2)          #{30}

##4.对称差集:symmetric_difference和^等价
print(s1.symmetric_difference(s2))#{20, 30}
print(s1 ^ s2)          #{20, 30}

集合生成式

#列表生成式
lst = [i * i for i in range(10)]
print(lst)      #[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

#集合生成式
set = {i * i for i in range(10)}
print(set)      #{0, 1, 64, 4, 36, 9, 16, 49, 81, 25}

frozenset不可变集合:让集合变成不可变类型

s = frozenset('barry')
print(s,type(s))  # frozenset({'a', 'y', 'b', 'r'}) <class 'frozenset'>

26.字符串

字符串的驻留机制:

from sys import intern
a = intern('hello!@'*20)
b = intern('hello!@'*20)
print(a is b)   #true
#可以指定驻留任意的字符串加入到小数据池中,让其只在内存中创建一个对象,多个变量都是指向这一个字符串。

字符串的查询操作

  1. index()方法:查找子串substr第一次出现的位置,如果查找的字串不存在时,则抛出ValueError.
  2. rindex()方法:查找子串substr最后一次出现的位置,如果查找的子串不存在时,则抛出ValueError.
  3. find()方法:查找子串substr第一次出现的位置,如果查找的字串不存在时,则返回-1.
  4. rfind()方法:查找子串substr最后一次出现的位置,如果查找的字串不存在时,则返回-1.
str = 'Hello,Hello'
print(str.index('lo'))#3
print(str.find('lo'))#3
print(str.rindex('lo')) #9
print(str.rfind('lo'))  #9

字符串的大小写转换操作
image.png

字符串内容对齐操作
image.png

字符劈分操作
image.png

s = 'hello,world,python'
#默认的劈分字符串是空格字符串
lst = s.split()
print(lst)      #['hello,world,python']
#指定劈分字符串
print(s.split(sep = ','))#['hello', 'world', 'python']
#同时指定最大劈分次数为1
print(s.split(sep = ',',maxsplit= 1))#['hello', 'world,python']

判断字符串操作的方法
image.png
字符串操作的其他方法
image.png

s = 'Hello,World,World,World'
print(s.replace('World','Python'))  #Hello,Python,Python,Python
print(s.replace('World','Python',2))#Hello,Python,Python,World

s1 = ['Hello','World','Python']
print('|'.join(s1))                 #Hello|World|Python

s2 = ('Hello','World','Python')
print(''.join(s2))                  #HelloWorldPython

字符串的比较操作
比较原理:两个字符进行比较时,比较的是ordinal value(原始值),调用内置函数ord()可以得到指定字符的原始值。与内置函数ord()相对应的是内置函数chr(),调用内置函数chr()可以得到指定原始值所对应的字符

s1 = 'apple'
s2 = 'app'
print(s1 > s2)  #true
print(ord('a')) #97
print(chr(97))  #a

#is和==的区别:is比较的是id(内存地址)是否相同,==比较的是value
a = b = 'python'
c = 'python'
print(a == c)   #True
print(a is c)   #True:字符串的驻留机制

字符串的切片操作
[start:end:step]:表示从start开始,end - 1结束(不包括end),步长为step

s = 'Hello,World,Python'
print(s[0:5:1]) #Hello
#使用逆向索引
print(s[::-1])  #nohtyP,dlroW,olleH
print(s[-6::])  #Python

格式化字符串

格式化字符串的两种方式:

  1. %作为占位符


2. {}作为占位符

name = '李四'
age = 23
#1.%
print('我叫%s,今年%d岁' % (name,age))    #我叫李四,今年23岁
#2.{}
print('我叫{0},今年{1}岁'.format(name,age))#我叫李四,今年23岁
#3.f-string
print(f'我叫{name},今年{age}岁')           #我叫李四,今年23岁

print("%10d" % 99)  #%10d表示输出的99占10个宽度,99不足10个宽度则左边空格占位
print("%.3f" % 3.14159)#3.142,%.3f表示输出的浮点数保留三位小数
print("%10.3f" % 3.14159)#输出的浮点数总共宽度为10,保留三位小数
print('{:10.3f}'.format(3.14159))#3.142, #同时设置宽度和精度

f[F]-strings格式化输出(推荐使用):
结构就是F(f)+ str的形式,在字符串中想替换的位置用{}展位,而format需要在字符串后面写入替换的内容。

# name = 'Jack'
# age = 23
#
# msg = F'姓名为:{name},年龄为:{age}'
# print(msg)    #姓名为:Jack,年龄为:23

# info = {'name':'Jack','age':23}
# msg = f"姓名为:{info['name']},年龄为:{info['age']}"
# print(msg)      #姓名为:Jack,年龄为:23

def sum(a,b):
    return a + b
print('求和的结果为:'+f'{sum(100,200)}')  #求和的结果为:300

#多行f的编写

name = 'barry'
age = 18
ajd = 'handsome'

# speaker = f'''Hi {name}.
# You are {age} years old.
# You are a {ajd} guy!'''

speaker = f'Hi {name}.'\
          f'You are {age} years old.'\
          f'You are a {ajd} guy!'
print(speaker)  #Hi barry.You are 18 years old.You are a handsome guy!

字符串的编码和解码:一句话就是解铃还须系铃人

#编码
s = '人生苦短'
#在GBK这种编码中,一个中文占据两个字节,英文还是使用一个字节
print(s.encode(encoding='GBK')) #b'\xc8\xcb\xc9\xfa\xbf\xe0\xb6\xcc'
#在utf-8中,一个中文占据三个字节,用1到6个字节编码Unicode字符
print(s.encode(encoding='utf-8'))#b'\xe4\xba\xba\xe7\x94\x9f\xe8\x8b\xa6\xe7\x9f\xad'

#解码
byte = s.encode(encoding='GBK') #编码
print(byte.decode(encoding='GBK'))#解码,人生苦短

# encode称作编码:将 str 转化成 bytes类型(将str转化成bytes类型是因为为了存储或者网络传输)
s1 = '中国'
b1 = s1.encode('utf-8')  # 转化成utf-8的bytes类型
print(s1)  # 中国
print(b1)  # b'\xe4\xb8\xad\xe5\x9b\xbd'

s1 = '中国'
b1 = s1.encode('gbk')  # 转化成gbk的bytes类型
print(s1)  # 中国
print(b1)  # b'\xd6\xd0\xb9\xfa'

# decode称作解码, 将 bytes 转化成 str类型
b1 = b'\xe4\xb8\xad\xe5\x9b\xbd'
s1 = b1.decode('utf-8')
print(s1)  # 中国

#GBK编码的bytes转化为UTF-8编码的bytes
s1 = '中国'
byte = s1.encode('GBK')
print(byte) #b'\xd6\xd0\xb9\xfa'

b1 = b'\xd6\xd0\xb9\xfa'
s = b1.decode('GBK')
b2 = s.encode('utf-8')
print(b2)   #b'\xe4\xb8\xad\xe5\x9b\xbd'

python中常用的数据结构总结

如下表所示:

数据结构 是否可变 是否重复 是否有序 定义符号
列表 可变 可以重复 有序 []
元组 不可变 可以重复 有序 ()
字典 可变 键不可重复,值可以 无序
集合 可变 不可重复 无序 {}
字符串 不可变 可重复 有序 ''或者""