• 08 Python基础数据结构


    目录:

    1) 列表

    2) 元组

    3) 字符串

    4) bytes

    5) bytearray

    6) 字典

    7) 集合

    8) 冻集合

    """
    1. 列表特性
    2. 创建
    3. 增加
    4. 删
    5. 改
    6. 查
    7. 切片
    8. 其他方法
    9. for循环注意的点
    10. 深浅copy问题
    """

    列表特性:
    1. 可变数据类型,可以存任意数据类型
    2. 有序

    Note:
    1. 两个列表就算元素相同,但如果顺序不同,那么就是不同的列
    ls = [1, 2, 3]
    ls2 = [2, 1, 3]
    print(ls == ls2)
    2. 少用pop和insert,在数据量大的时候效率低

    创建:
    # 方法一
    created_list1 = [] # 空列表
    created_list1 = [1, '2', 3.0, 4+0j, b'abc', (1, 2), [1, 2], {1, 2}, {'k1': 'v1'}]
    print(created_list1)

    # 方法二
    created_list2 = list() # 空列表
    created_list2 = list(range(10))
    print(created_list2)

    # Note: 方法三
    # 这种方式只是给created_list1起了一个别名,
    # 他们操作的都是同一个对象
    created_list3 = created_list1

    增加:
    ls = list(range(10))

    # 追加
    # 向列表最后追加一个任意类型的元素
    ls.append('abc')
    print(ls)

    # 插入
    # 在指定位置插入一个任意类型的元素
    ls.insert(1, ['a', 'b', 'c'])
    print(ls)

    # 批量增加
    # 在列表最后增加多个元素
    ls.extend(['1d', '2e', '3f', '4g'])
    print(ls)

    # 批量插入
    # 在指定位置插入多个元素
    ls[0:0] = 'xyz' # ls[0:0]结果为空列表,在索引为0的前面插入'x', 'y', 'z'
    print(ls)


    删除:
    # del
    # del ls[1]
    # del ls[0:0]
    # print(ls)
    # del可以删任何东西
    # del ls
    # print(ls)

    # pop()
    # 默认删除最后一个,并返回被删除的元素
    # print(ls.pop())
    # 可以指定删除谁
    # print(ls.pop(-1))
    # 如果索引超过范围,则报错IndexError

    # remove()
    # 删除遇到指定的第一个值,如果指定的值有多个,只删除遇到的第一个值
    # ls.remove(1)
    # print(ls)
    # 如果将要删除的值不存在,则报错ValueError

    # clear()
    # 将列表清空
    # ls.clear()
    # print(ls)

    # 将某一部分清空
    # ls[:4] = []
    # print(ls)
    # ls[:] = [] # 与clear()作用一样
    # print(ls)

    改:
    # 索引方式修改
    ls[0] = 'a'
    print(ls)

    # 切片方式修改
    # 等量修改
    ls[0:4] = ['A', '一', '二', '三']
    print(ls)
    ls[:-7:-1] = ['九', '八', '七', '六', '五', '四']
    print(ls)

    # 不等量修改
    ls[0:4] = list(range(20))
    print(ls)
    # 右往左不等量修改不允许,(毕竟列表在内存中的起始位置确定了,个人猜想)
    # 超过范围,不允许
    # ls[:-len(ls) + 1:-1] = list(range(100))
    # print(ls)
    # 未超过范围,不允许
    # ls[:-7:-1] = [-1, -2, -3, -4, -5, -6, -7]
    # print(ls)

    # 当然,不等量修改是建立在步长为1的情况下
    # 如果步长不为1,那么就只能等量修改
    # ls[:4:2] = 'abcd' # 不允许
    # print(ls)
    ls[:4:2] = 'ab' # 正解
    print(ls)

    查:
    Note:
    负步长取的值是从右往左取,并且按照左往右方向排列 (总是弄混)

    ls = [1, 2, 3]
    print(ls)
    print(ls[0])
    print(ls[-1])

    切片:
    print(ls[0:5]) # 顾头不顾尾
    print(ls[:5]) # 如果起始位置为0的话,可以省略
    print(ls[1:-1]) # 有正索引,也有负索引;正,从左往右以0开始;负,从右往左以-1开始
    print(ls[1:]) # 如果省略终止位置,则默认取到最后一个元素
    print(ls[:]) # 取全部元素
    print(ls[:6:2]) # 在[0 - 5]之间每隔两个取一个,2称之为步长;步长默认为1
    print(ls[-9:-2:2])
    # 如果步长为正整数,那么起始索引必须 < 终止索引
    # 起始索引 <= 终止索引也可以,只不过取到的是空列表
    print(ls[6:2:-1]) # 步长为负1,在[6 - 1]之间每隔一个取一个
    print(ls[::-1]) # 列表反序输出
    # 如果步长为负整数,那么起始索引必须 > 终止索引
    # 起始索引 >= 终止索引也可以,只不过取到的是空列表
    print(ls[:100]) # 切片的终止位置可以超出列表长度,尽可能地多取元素
    print(ls[:100:2])
    print(ls[:-100:-1])

    其他方法:
    *乘法操作
    +加法操作
    反转
    排序
    长度
    计数
    查询索引

    ls = list(range(5))
    print(ls)

    # *乘法操作
    ls = ls * 2
    print(ls)

    # +加法操作,类似extend()
    ls = ls + ['a', 'b', 'c']
    print(ls)
    # 不仅可以加同类
    # 还可以加不同类(容器类型),但必须是复合操作符
    # 元组、列表、字符串、字典(加键)、集合、冻结集合
    ls += 'efghi'
    print(ls)
    ls += 1, 2, 3
    print(ls)

    # 反转
    ls.reverse()
    print(ls)

    # 排序
    # 前提是元素类型要一致
    ls2 = list(range(10))
    ls2.sort() # 默认升序
    print(ls2)
    ls2.sort(reverse=True) # 降序
    # key参数以后介绍
    print(ls2)

    # 长度
    print(len(ls))
    print(ls.__len__())
    # len()内部就是调用的__len__()

    # 计数
    print(ls.count(2)) # 存在,则返回个数
    print(ls.count(100)) # 不存在,则返回0

    # 查询索引
    # 在指定的范围内,返回遇到的第一个值的索引,如果有多个值相同,只返回第一个值的索引
    print(ls.index(2))
    print(ls.index(2, 1, 5))
    # 如果查询的值不存在,则报错ValueError
    # print(ls.index(100))

    for循环注意的点
    Note:
    循环一个列表的时候,不要修改他的大小,会有问题
    解决方法之一:
    反向循环,从右往左循环
    解决方法之二:
    将要删除的元素放到另一个列表中


    # 方法一:
    for index in range(len(ls)-1, -1, -1):
    if ls[index] % 2 == 0:
    ls.pop(index)
    # print(l1)

    # 方法二:
    del_ls = []
    ls = list(range(10))
    for item in ls:
    if item % 2 == 0:
    del_ls.append(item)
    for item in del_ls:
    ls.remove(item)

    # 方法三:(但是我觉得这种浪费空间)
    ls = list(range(10))
    # for item in ls[::]:
    for item in ls[::-1]:
    if not item % 2:
    ls.remove(item)
    print(ls)

    10. 深浅copy问题

    ls = list(range(10))
    ls.append(['a', 'b', 'c'])
    # 浅copy
    # copy的时候,只是创建了新的列表对象,新列表中每个元素的引用都是指向的被copy列表的每个元素的引用
    ls2 = ls.copy()
    print(ls2 is ls)
    print(ls2[0] is ls[0]) # True,表示是同一块内存地址
    print(ls2[-1] is ls[-1])
    # 所以,对其中一个列表中的可变数据类型进行更改,另一个列表页能感知到
    ls[-1].append('d')
    print(ls2)

    # 以下操作都是浅copy
    # 创建了新的列表,只是copy了被copy列表对象的引用
    # 虽然是不同的容器,但是里面的值都是同一个值
    # 1. ls2 = ls.copy()
    # 2. ls2 = ls[:]
    # 3. ls2 = list(ls)
    # 4. import copy
    # ls2 = copy.copy(ls)

    # 深copy
    # Note: 非特殊情况,不要用深copy,当数据量大的时候,耗费容量
    # 完全独立的两个列表对象,不管是容器本身还是里面的元素
    # 准确来讲,是容器和里面的容器类型都是独立的
    # 不可变数据类型在他们的一定范围内,都是同一个值,共用同一块内存

    # import copy
    # ls2 = copy.deepcopy(ls)
    # print(ls2[-1] is ls[-1]) # 为False,说明不是同一块内存空间
    # print(ls2[0] is ls[0]) # 不可变数据类型,在一定范围内,都是共用同一块内存空间

    """
    1. 元组特性
    2. 创建
    3. 查
    4. 切片
    5. 其他方法
    """

    元组特性:
    相当于只读列表

    1,不可变数据类型
    2,元组本身不可变,但是如果其中包含其他可变数据类型,则可对这些类型进行修改
    3,有序

    应用场景:
    1,显示地告诉别人,此处数据不可修改
    2,数据库连接配置信息等

    Note:
    元组中最好不放其他容器类型
    元组的效率实际上比列表高


    创建:
    # 方式一
    tp = ()
    tp = (1, 2, 3)
    tp = (1,) # 逗号不能少
    print(tp)

    # 方式二
    tp2 = 1, 2, 3
    print(tp2)

    # 方式三
    tp3 = tuple(range(10))
    print(tp3)

    # 特别注意:
    tp4 = tp3
    # 道理跟列表一样

    查:
    tp[0]
    tp[-1]

    切片:
    tp[:]

    其他方法及操作:
    count()
    index()
    tp *= 3
    tp += tp2

    """
    1. 字符串特性
    2. 创建
    3. 删
    4. 查
    5. 切片
    6. 方法
    基本方法
    split和splitlines区别
    strip注意事项:
    isdigit / isdecimal / isnumeric区别
    7. 字符串拼接
    """

    字符串特性:
    不可变数据类型

    创建空字符串:
    s = str()
    s = ''
    NOTE:
    空字符串是任何字符串的子字符串

    方法:
    字母类:
    captialize()
    1,将字符串的第一个字母大写,如果第一个字符为字母的话
    2,将字符串的除了第一个字母外其他字母部分变成小写,如果有的话
    casefold()
    有些国家的小写不一样
    lower()
    将字符串的字母部分变成小写
    upper()
    将字符串的字母部分变成大写
    title()
    将由非字母分隔的全部英文单词的第一个字母变成大写
    swapcase()
    大写变小写,小写变大写

    对齐类:
    center()
    将字符串在指定宽度范围内居中对齐,两边默认填充字符为空格
    ljust()
    左对齐
    rjust()
    右对齐
    zfill()
    将字符串在指定宽度范围内右对齐,填充字符为0;
    Note:
    如果第一个字符是+或-,填充字符0将在其后填充

    分隔类:
    split()
    默认分隔符为空白字符,maxsplit指定分隔的次数
    rsplit()
    从右边开始分隔
    splitlines()
    跟split(' ')有一点点区别,看后续介绍
    参数 keepends=True/False,表示是否保留
    partition()
    一个元组(指定字符前的 ,指定字符, 指定字符后面的)
    rpartition()
    从右边开始分

    剥夺类:
    strip()
    剥夺字符串两边指定的字符,默认为空白字符
    lstrip()
    剥夺字符串左边指定的字符,默认为空白字符
    rstrip()
    剥夺字符串右边指定的字符,默认为空白字符

    编码解码类:
    encode()
    编码,默认utf-8,执行目标为str
    encoding='utf-8'
    errors='strict' 遇到非法字符时,直接抛出异常
    ignore 忽略非法字符
    replace 用?代替非法字符
    decode()
    解码,默认utf-8,执行目标为bytes

    原则:用什么编码就用什么解码

    加密类:
    str.maketrans()
    指定加密规则
    str为str类或者任何str类型的数据
    # 如果只有一个参数,那么参数必须为字典
    # 字典的键可以为Unicode字符、Unicode字符对应的整数值、以及None,字典的值也一样;
    # None表示删除
    如果有两个参数或者三个
    intab = '123' # intab和outtab要一一对应
    outtab = 'abc'
    deltab = 'qdy' # 也可以不指定deltab
    rules = str.maketrans(intab, outtab, deltab)
    print('123abcqdy123'.translate(rules))
    translate()
    加密

    替换类:
    replace()
    将原字符串中的被替换字符串按照指定替换次数替换成新字符串,默认全部替换
    expandtabs()
    更改字符串中的 的大小,默认为8
    参数:tabsize

    查找类:
    index()
    从左开始查找第一个指定字符对应的索引;
    没有找到的话,则报异常
    rindex()
    从右开始查找第一个指定字符对应的索引;
    没有找到的话,则报异常
    find()
    从左开始查找第一个指定字符对应的索引;
    没有找到的话,则返回-1
    rfind()
    从右开始查找第一个指定字符对应的索引;
    没有找到的话,则返回-1
    count()
    统计指定字符在字符串中出现的次数
    没有指定字符的话,返回0

    加入类:
    join()
    将一个字符加入到每一个元素为字符的迭代对象中

    格式化类:
    %
    format()
    format_map()

    判断类:
    startswith()
    endswith()
    isascii()
    isalpha()
    isupper()
    islower()
    istitle()
    isalnum()
    isdigit()
    isdecimal()
    isnumeric()
    isspace()
    isidentifier()
    isprintable()

    其他:
    len()
    del
    +
    *

    # strip注意事项:
    剥夺字符串两边指定的字符,默认为空白字符
    空白字符包括:



    v
    f
    空格
    Note:只要两边出现了指定字符串中的任意一个,
    都将其去除,而不是说出现整体才去除(lstrip和rstrip同)


    # split和splitlines区别
    # 一,split
    # 1, 当使用默认参数的时候以 fv 空格当分隔符
    # 'abc ' --> ['abc']
    # 'abcf ' --> ['abc']
    # ' ' --> []
    # 2, 当指定了默认参数
    # 'abc ' --> ['abc', '']
    # 'abcf ' --> ['abc', '', '']
    # ' ' --> ['', '']
    # 3, 当指定了除开默认参数的其他值
    # 'abc123' --> ['abc', '']
    # '123' --> ['', '']

    # 二,splitlines
    # 'abc ' --> ['abc']
    # 'abcf ' --> ['abc', ''] # 只有f才会这样,估计把f当作 了
    # 'abc ' --> ['abc', '']
    # ' ' --> ['']
    # 相当于是:遇到 ,就把 之前的字符以及 拿出来,放到一个列表中。
    然后再看keepends的值,如果为False,就不保留 ,如果为True,就保留

    # isdigit / isdecimal / isnumeric区别

    # isdigit()
    # True: Unicode数字,全角数字(双字节), byte数字(单字节)
    # False: 汉字数字, 罗马数字
    # Error: 无
    #
    # isdecimal()
    # True: Unicode数字,全角数字(双字节)
    # False: 罗马数字,汉字数字
    # Error: byte数字(单字节)
    #
    # isnumeric()
    # True: Unicode数字,全角数字(双字节),罗马数字,汉字数字(壹、一)
    # False: 无
    # Error: byte数字(单字节)

    # 字符串拼接

    # 方式一:+加法操作符
    s = '123'
    s += '456'
    print(s)

    # 方式二:join
    print('-'.join('123'))
    # 加法与join的区别
    # 1,如果拼接后的长度不超过20,+比join高效
    # 2,如果长度超过20,则高版本解释器选择f'{}',低版本选用join

    # 方式三:格式化类


    """
    1. bytes特性
    2. 创建
    3. 删
    4. 查
    5. 切片
    6. 方法
    """

    bytes特性:
    不可变数据类型

    创建:
    b = bytes()
    b = b'' / B''
    b = b'123abc' # 仅支持ascii字符

    b = bytes(10)
    b = bytes('琴师晃', encoding='utf-8', errors='strict')
    b = bytes(range(10))

    方法:
    # 除了decimal和numeric其他都支持
    # 自带2个方法
    # hex()
    # 将字符ASCII值二进制转换为字符串类型的十六进制
    print(b'abc'.hex(), type(b'abc'.hex()))

    # fromhex()
    # 参数为字符串,内容为16进制的数码
    # 成双出现,每一对是16进制
    # 最后显示的结果为如果能用ASCII显示的就用ASCII字符显示,不能的话就16进制序列
    print(bytes.fromhex('ff22'))

    """
    1. bytearray特性
    2. 创建
    3. 删
    4. 查
    5. 切片
    6. 方法
    """

    bytearray特性:
    可变的bytes

    创建:
    b = bytearray()
    b = bytearray(b'123')
    ...

    方法:
    1. 支持str所有方法,除了decimal和numeric
    2. 支持bytes的hex和fromhex
    3. 支持列表的
    append、insert、extend、
    pop、remove、clear、copy、reverse

    """
    1. 字典特性
    2. 创建
    3. 删
    4. 改
    4. 查
    5. 循环
    6. 方法
    """

    字典特性:
    1. 可变数据类型
    2. 无序


    创建:
    NOTE:
    键只能是可hash的,也就是不可变数据类型

    # 方式一
    dc = {}
    dc = {'k1': 'v1', 'k2': 'v2'}
    print(dc)
    # Note:同时存在键1和True
    # 只会显示1,True当1用
    dc2 = {1: '1', True: 'True'}
    print(dc2)

    # 方式二
    dc2 = dict()
    dc2 = dict(dc)
    dc2 = dict(name='123', age=20)
    dc2 = dict([('sex', 'Male'), ('class', 2)])
    print(dc2)

    # 方式三
    dc3 = dict.fromkeys(['name', 'age', 'sex'])
    print(dc3)
    dc3 = dict.fromkeys(['name', 'age', 'sex'], 10)
    print(dc3)
    # Note: 有一个坑,如果都初始化一个可变数据类型的话,
    # 一个改,其他都改

    增:
    # 方式一
    dc = {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
    dc['k1'] = 90
    print(dc)

    # 方式二
    # setdefault

    # 方式三
    # 键是唯一的,后来居上
    # update()方法
    dc2 = {'k1': 'qdy', 2: 3, (4, 6): [1, 2, 3]}
    dc.update(dc2)
    dc.update(k1='QinDongyu', name='第一')
    dc.update([('sex', 'Male'), ('class', 2)])
    print(dc)

    删:
    dc = {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
    # 方式一
    # del dc['k1']
    # print(dc)

    # 方式二
    # pop()
    # 如果键存在,则删除对应的键值对,并且返回键对应的值
    # print(dc.pop('k1'))
    # print(dc)
    # 如果键不存在,并且不指定返回值的话,会报错KeyError
    # print(dc.pop('k6'))
    # print(dc.pop('k6', 'No this key'))
    # print(dc)

    # 方式三
    # popitem()
    # 随机删
    # print(dc.popitem())

    # 方式四
    # clear()
    # dc.clear()
    # print(dc)

    查:
    # 方式一
    dc = {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
    print(dc['k1'])

    # 方式二
    # get()方法
    # 如果键存在,则返回对应的值;
    print(dc.get('k1'))
    # 如果键不存在,默认情况下则返回None,可以自己指定返回的值
    print(dc.get('k11'))
    print(dc.get('k11', 'No this key'))

    # 方式三
    # setdefault()方法
    # 如果键存在,则返回对应的值
    print(dc.setdefault('k1'))
    # 如果键不存在,则创建键'k1'以及值None,默认情况下,并返回创建的值
    # print(dc.setdefault('k11'))
    print(dc.setdefault('k11', 'v11'))
    print(dc)

    其他:
    len()
    copy()

    循环:
    Note:循环一个字典的时候,不要去修改他的大小,会出错

    dc = {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
    for key in dc:
    print(key) # 打印的是键

    # dc.keys()获取所有的键
    # 可迭代、可转换、可参与集合运算、不支持索引
    for key in dc.keys():
    print(key)
    else:
    print(dc.keys())

    # dc.values()获取所有的值
    # 可迭代、可转换、不支持索引
    for key in dc.values():
    print(key)
    else:
    print(dc.values())

    # dc.items()获取所有的键值对
    # 可迭代、可转换、不支持索引
    for key, value in dc.items():
    print(key, value)
    else:
    print(dc.items())

    # 其实这种方式比上面效率更高,因为下面直接通过hash取值
    for key in dc:
    print(key, dc[key])
    else:
    print(dc.items())


    """
    1. 集合特性
    2. 创建
    3. 删
    4. 增
    5. 循环
    6. 运算
    """

    集合特性:
    可变数据类型
    去重
    无序(虽然无序,但会按照某种规则显示)
    (就是字典的键)

    创建:
    s = set()
    s = set('123123123')

    增:
    st = {1, 2, 3}

    # add
    # 增加一个可hash的数据类型
    st.add(4)
    print(st)

    # update
    # 增加多个可hash的数据类型
    st.update('abc')
    print(st)
    st.update(['A', 'Z'], '456', ('a', 'b'))
    print(st)

    st = set(range(10))

    删:
    # pop
    # 随机删,并返回,如果集合为空,报错KeyError
    ret = st.pop()
    print(ret)
    print(st)

    # remove
    # 删除一个元素,如果不存在,则报错KeyError
    # st.remove(3)
    # print(st)
    # st.remove(10) # 报错

    # discard
    # 删除一个元素,如果不存在,不报错
    st.discard(10)

    # clear
    # 清空
    st.clear()

    # copy()

    运算:
    st = {1, 2, 3, 4}
    st2 = {2, 4, 'a', 'b'}

    # 交
    # 方式一:
    # print(st & st2)
    # st &= st2
    # 方式二:
    # print(st.intersection(st2))
    # st.intersection_update(st2)
    # print(st)

    # 并
    # 方式一:
    # print(st | st2)
    # st = st | st2
    # print(st)
    # 方式二:
    # print(st.union(st2))

    # 差
    # 方式一:
    # print(st - st2)
    # print(st2 - st)
    # st -= st2
    # print(st)
    # st2 -= st
    # print(st2)
    # 方式二:
    # print(st.difference(st2))
    # print(st2.difference(st))
    # st.difference_update(st2)
    # print(st)
    # st2.difference_update(st)
    # print(st2)

    # 对称差集
    # 方式一:
    # print(st ^ st2)
    # st ^= st2
    # print(st)
    # 方式二:
    # print(st.symmetric_difference(st2))
    # st.symmetric_difference_update(st2)
    # print(st)

    # 判断是否为子集
    st = {2, 4}
    st2 = {2, 4, 'a', 'b'}
    # 方式一:
    # <
    # 要求父集必须大于子集
    # print(st < st2) # 判断st是否是st2的子集
    # st2 = {2, 4}
    # print(st < st2)
    # # <=
    # print(st <= st2)
    # 方式二:
    # print(st.issubset(st2)) # issubset 等同于 <=

    # 判断是否为父集
    st = {2, 4}
    st2 = {2, 4, 'a', 'b'}
    # 方式一:
    # >
    # 要求父集必须大于子集
    # print(st2 > st) # 判断st2是否是st的父集
    # st2 = {2, 4}
    # print(st < st2) # False
    # # >=
    # print(st2 >= st)
    # 方式二:
    # print(st2.issuperset(st)) # issuperset 等同于 >=

    # 判断是否不相交
    # print(st.isdisjoint(st2))

    """
    1. 冻集合特性
    2. 创建
    3. 方法
    """

    特性:
    集合的不可变版本

    创建:
    fz = frozenset()
    fz = frozenset('123123')

    方法:

    intersection
    union
    difference
    symmetirc_difference
    issubset
    issuperset
    isdisjointt

    fz = frozenset(range(10))
    fz2 = frozenset(range(10))
    print(fz & fz2)
    fz = fz & fz2 # 支持复合
    print(fz)

  • 相关阅读:
    安装IIS的郁闷之旅
    设置WPF窗口相对于非WPF窗口的位置
    钓鱼记
    java拾遗
    人间四月芳菲尽
    [linux] x server can not start under VMWare
    如果没有开源软件没有免费软件,这个世界会怎么样?评[盖茨北大演讲遭遇开源人士抗议]
    程序员的面包
    2007中国软件英雄会-七年的等待
    sysbench安装
  • 原文地址:https://www.cnblogs.com/hardy9sap/p/10602747.html
Copyright © 2020-2023  润新知