zoukankan      html  css  js  c++  java
  • python | 可变数据类型-列表/字典/集合

     

    2.5 列表(list)

    2.5.1 索引和切片

    列表的索引和切片,用法和字符串的索引和切片一模一样,区别在于,面临二维或多维列表时,会有多重索引和切片,思路就是「一层一层往里剥」。

    L = [1, 2, 3, 4, [9, 8, 7, 6]]
    
    len(L)
    L[4]
    L[4][1]
    L[4][::-1]
    

     

    2.5.2 常用方法

    2.5.2.1 添加元素

    方法 含义 原地操作?
    append(x) 将元素x添加至列表尾部
    extend(L) 将列表L中所有元素添加至列表尾部
    insert(index, x) 在列表指定位置index处添加元素x,该位置后面元素后移一位 新生成
    + 添加元素至列表尾部 新生成
    * 拼接字符串 新生成
    alist = [1, 2, 3]
    blist = [4, 5, 6]
    alist.extend(blist)  # blist添加至alist后面,原地操作
    alist
    
    alist.append(blist)
    alist
    
    # append和+的区别
    import time
    result = []
    start = time.time()  # 返回当前时间
    for i in range(10000):  # 创建一个整数列表
        result = result + [i]
    print('+添加:', time.time()-start)  # 打印列表长度,并计算耗时
    
    result = []
    start = time.time()
    for i in range(10000):
        result.append(i)
    print('Append:', time.time()-start)
    
    # append和insert区别
    import time
    a = []
    start = time.time()
    for i in range(100000):
        a.insert(0, i)
    print('Insert:', time.time()-start)  # 新生成
    
    a = []
    start = time.time()
    for i in range(100000):
        a.append(i)
    print('Append:', time.time()-start)  # 原地操作
    
    L = [1, 2, 3, 4, 5, 6]
    L*3  # 通过乘实现复制
    

     

    2.5.2.2 删除元素

    方法 含义 原地操作?
    remove(x) 删除首次出现的指定元素x
    pop(index) 删除指定index元素,并返回该元素的值,index默认-1
    clear(index) 删除列表中所有元素,保留列表对象
    del 删除列表中元素或整个列表 /
    赋值 对列表中元素或整个列表进行赋值,也算一种删除

    拓展:删除列表重复元素有两种思路:

    • for循环中的i基于内容去遍历,用i in list[:]
    • for循环中的i基于index去遍历,用i in range(len(list)-1, -1, -1)
    L = [1, 2, 3, 4, 4, 5, 6]
    L.remove(4)  # 原地操作
    L
    
    # 删除重复元素法1
    x = [3, 4, 5, 5, 6]
    for i in x[:]:  # 采用切片的方式
        print(i)
        if i == 5:
            x.remove(i)
    print(x)
    
    # 删除重复元素法2
    x = [3, 4, 5, 5, 6]
    for i in range(len(x)-1, -1, -1):  # 从后向前的顺序
        print(i)
        if x[i] == 5:
            del x[i]
    print(x)
    
    L = [2, 3, 4, 5]
    L.pop(2)  # 实现两个功能:取出4,把4从原列表删除
    
    L = [2, 3, 4, 5]
    L.clear()
    L
    
    L = [1, 2, 3, 4, 5]
    id(L)
    L[0:2] = [6, 6]  # 修改多个元素
    L
    id(L)
    
    L = [1, 2, 3, 4, 5]
    del L[1]  # 删除第一个
    L
    del L  # 删除整个列表
    L
    

     

    2.5.2.3 计算&排序

    方法 含义 原地操作?
    index(x) 返回列表中第一个值为x元素的下标,若不存在则抛出异常 /
    count(x) 返回指定元素x在列表中出现的次数 /
    reverse() 对列表所有元素进行逆序
    sort(key=,reverse=) 对列表元素进行排序,key指定排序依据,reverse决定升序降序:True降序、False升序

     
    需要注意,reverse方法和sort方法,都有对应的排序函数:

    函数 含义 原地操作?
    reversed(L) 对列表L所有元素进行逆序,返回是一个迭代器,需要list化显示
    sorted(list, key=, reverse=) 对列表元素进行排序,key指定排序依据,reverse决定升序降序:True降序、False升序 新生成

    且无论是在sort还是sorted排序中,参数key通常采用匿名函数「lambda」。

    x = [3, 4, 5, 6]
    x.index(5)   # 返回索引,不存在则报错
    x.count(10)  # 没有返回0,不会报错
    x.reverse()  # 原地逆序
    x
    
    x = [2, 3, 1, 5, 8]
    x.sort()  # 默认是升序
    x
    x.sort(reverse=True)  # 降序
    x
    
    # 自定义排序,使用匿名函数
    aList = [[3, 4], [15], [11, 9, 17, 13], [6, 7, 5]]
    aList.sort(key=lambda x: len(x), reverse=True)  # 按长度排序,lambda函数,匿名函数
    aList
    
    x = [1, 2, 3, 4, 5]
    list(reversed(x))  # 新生成
    
    student = [['john', 'A', 15], ['jane', 'B', 12], ['dave', 'B', 10]]  # 按值进行排序
    sorted(student, key=lambda a: a[2], reverse=True)
    

     

    2.5.2.4 类型转换

    字符串和列表经常互相转换,具体方法是listjoin:

    • 函数list(str):把字符串转化为列表
    • 方法' '.join(L):把列表转化为字符串
    s = 'abcd'
    list(s)
    
    x = ['apple', 'peach', 'banana', 'peach', 'pear']
    '/'.join(x)
    

     

    2.5.2.5 复制

    常见的复制有三种:赋值、浅拷贝、深拷贝,三者在使用和表现上都存在区别。

     

    2.5.2.5.1 赋值

    赋值操作是复制了引用指针,所以数据一方改变,必然导致另一方变化,原理见下图:

    # 实质是复制了引用:一方改变,必然导致另一方变化
    L1 = [1, 2, 3, 4]
    id(L1)
    L2 = L1
    L2[0] = 0
    L2
    id(L2)
    L1
    

     

    2.5.2.5.2 浅拷贝

    浅拷贝有4种形式,而不同维度的数据,在浅拷贝后数据的变化也不尽相同,需要分开讨论,原理见下图及代码:

    • copy()方法
    • 使用列表生成式
    • 用for循环遍历
    • 切片
    # 一维:原来值和浅拷贝值互不影响
    L1 = [1, 2, 3, 4]
    L2 = L1[:]
    L2[0] = 0
    L2
    L1
    
    # 二维或多维:分两种情况讨论
    x = [1, 2, 3, [4, 5, 6]]
    y = x[:]
    y[0] = 0         # 复杂子对象不改变:原来值和浅拷贝值互不影响
    y
    x
    
    x = [1, 2, 3, [4, 5, 6]]
    y = x[:]
    y[3][2] = 10     # 复杂子对象改变:原来值和浅拷贝值互相影响
    y
    x
    

     

    2.5.2.5.3 深拷贝
    • 深拷贝是完全的拷贝,原来值和深拷贝值互不影响
    • 使用copy模块中的deepcopy()方法生成
    import copy
    
    L1 = [1, 2, 3, [4, 5]]
    L2 = copy.deepcopy(L1)
    
    L2[0] = 0
    L2
    L1         # 原来值和深拷贝值互不影响
    

     

    2.5.3 内置函数

    函数 含义 是否新生成
    len() 返回列表中的元素个数 /
    max()、min() 返回列表中的最大、最小元素 /
    sum() 对列表元素进行求和运算 /
    zip() 将多个列表对应位置的元素组合成元组,返回可迭代的zip对象
    enumerate() 枚举列表元素,返回元组迭代器,元组中元素包含列表下标、元素的值
    L = [1, 2, 3, 4, 5, 6]
    sum(L)
    
    L1 = ['a', 'b', 'c']
    L2 = [1, 2, 3]
    list(zip(L1, L2))  # 生成的是元组迭代器
    
    # 把下标和值打印出来
    L1 = ['a', 'b', 'c']
    for i, j in enumerate(L1):
        print(i, j)
    

     

    2.5.4 列表推导式

    • 阅读:先看第一个for,再看第二个for,再看条件判断(if),最后看输出结果(表达式)
    • 格式
      • [表达式 for 变量 in 列表]
      • [表达式 for 变量 in 列表 if 条件]
    • 作用
      • 实现嵌套列表的平铺
      • 过滤不符合条件的元素
      • 使用多个循环实现多序列元素的任意组合
      • 实现矩阵转置
      • 使用函数或复杂表达式
      • 实现向量的运算
    # 用for循环实现
    L1 = [1, 2, 3, 4, 5]
    L3 = []
    for i in L1:
        L3.append(i**2)
    L3
    
    L1 = [1, 2, 3, 4, 5]
    [i**2 for i in L1]   # 列表推导式
    squar1 = map(lambda x: x**2, L1)  # 用map函数实现对L1的指定映射
    list(squar1)
    
    # 列表推导式,加上判断条件
    L1 = [1, 2, 3, 4, 5]
    [i**2 for i in L1 if i > 2]
    [[i, j] for i in range(10) for j in range(10) if i == j]
    
    L1 = [1, 2, 3, 4]
    L2 = [4, 5, 6, 7]
    [L1[i]+L2[i] for i in range(len(L1))]
    
    
    L1 = [1, 2, 3, 4]
    L2 = [4, 5, 6, 7]
    [L1[i]+L2[j] for i in range(len(L1)) for j in range(len(L2)) if i == j]
    

     

    2.6 字典(dictionary)

    2.6.1 创建

    字典有三种创建方式:

    • 直接赋值创建
    • dict()函数创建
    • 通过给定键值对创建
    # 直接赋值创建
    addresbook1 = {"小明": "1521055", "小华": "1872345", "小芳": "1389909"}
    addresbook1
    
    # 用dict()函数创建
    alist = [1, 2, 3]
    blist = ['a', 'b', 'c']
    dict(zip(alist, blist))   # 将多个列表对应位置的元素组合成元组,返回可迭代的zip对象
    
    # 通过给定键值对创建
    dict(name='小明', age=20)  # 等号前是键,等号后是值
    

     

    2.6.2 读取

    读取原理:通过key访问value

    方法 含义
    [key] 以键作为下标读取元素,若不存在则抛出异常
    get(x[,y]) 通过键x访问字典:若x存在返回对应的值;若x不存在返回none;若指定了y则x不存在返回y
    keys() 返回键的列表
    values() 返回值的列表
    items(x) 返回元组组成的列表,每个元组由字典的键和相应值组成
    copy() 对字典进行浅复制
    clear() 删除字典所有元素,保留空字典
    addressbook1 = {"小华": "1872345", "小明": "1521055", "小芳": "1389909"}
    
    addressbook1["小明"]     # 通过key访问value
    addresbook1.get('小明')  # 存在key时,返回对应的值
    addresbook1.get('小红')  # 不存在key时,返回none
    addresbook1.get('小红', 110)  # 不存在key时,返回指定的值
    addresbook1.keys()
    addresbook1.values()
    addresbook1.items()
    addresbook1.clear()
    addresbook1
    

     

    2.6.3 添加与修改

    方法 含义
    update() 更新信息:把一个字典的键值对添加到另一字典中去,若存在相同的key,则用后者覆盖
    pop() 删除指定key,并返回key对应的值
    指定键为字典赋值 若键存在则修改键的值,若键不存在则新增键值对
    值为可变数据类型 可进行相应数据类型的操作
    addresbook1 = {"小明": "1521055", "小华": "1872345", "小芳": "1389909"}
    addresbook1['小红'] = '378598345'  # 指定键为字典赋值
    addresbook1
    
    # 更新信息,若第一个字典的key在第二个字典也存在,则值以第二个字典的为准
    addresbook1 = {"小明": "1521055", "小华": "1872345", "小芳": "1389909"}
    addresbook2 = {"小华": "23462346", "小李": "0346246457"}
    addresbook1.update(addresbook2)
    addresbook1
    
    # pop用法和作用同列表中pop一样
    addresbook1 = {"小明": "1521055", "小华": "1872345", "小芳": "1389909"}
    addresbook1.pop('小明')
    addresbook1
    
    # 值可以为可变序列
    addresbook1 = {"小明": "1521055", "小华": "1872345",
                   "小芳": [1389909, 1895436, 2748579]}
    addresbook1
    addresbook1["小芳"].append(9999999)
    addresbook1
    

     

    2.6.4 字典推导式

    字典推导式语法类似于列表推导式,可快速生成符合指定条件的字典,只是外面是{ }。

    # 生成键为序号,值为字符串的字典
    {i: str(i) for i in range(5)}
    
    # 将两个序列关联生成,生成字典
    x = ['A', 'B', 'C', 'D']
    y = ['a', 'b', 'b', 'd']
    {x[i]: y[i] for i in range(len(x))}
    {i: j for i, j in zip(x, y)}
    
    # 随机产生1000个字符,统计字符次数
    import string  # 导入string模块
    import random  # 导入random模块
    x = string.ascii_letters + string.digits + string.punctuation  # 生成字符串
    y = [random.choice(x) for i in range(1000)]    # 列表推导式
    d = dict()
    for ch in y:
        d[ch] = d.get(ch, 0) + 1  # 不断统计,更新键的值,之前没有值则计1,有则取出加1
    d
    
    scores = {"Zhang San": 45, "Li Si": 78, "Wang Wu": 40, "Zhou Liu": 96,
              "Zhao Qi": 65, "Sun Ba": 90, "Zheng Jiu": 78, "Wu Shi": 99, "Dong Shiyi": 60}
    scores.values()
    
    max(scores.values())  # 最高分
    min(scores.values())  # 最低分
    sum(scores.values())/len(scores)  # 平均分
    [name for name, score in scores.items() if score == max(scores.values())]    # 最高分同学
    [name for name, score in scores.items() if score > (
        sum(scores.values())/len(scores))]  # 高于平均分同学
    

     

    2.7 集合(set)

    集合最大的应用场景,就是「去重」。

    2.7.1 创建

    集合有两种常见创建方式:

    • 直接赋值创建
    • set(x)函数创建
    a = {1, 2, 3, 4}   # 直接赋值创建
    a
    
    b = [5, 6, 7, 8]   # set()函数创建
    set(b)
    

     

    2.7.2 基本操作

    基本操作共有4种:交集(&)、并集(|)、差集(-)、补集(^)。

    a = {1, 2, 3, 4}
    b = {2, 3}
    
    a & b
    a | b
    a - b
    a ^ b
    

     

    2.7.3 包含关系测试

    包含关系测试常用于两集合关系判断,返回布尔值。

    方法 含义
    x.issubset(y) 判断x是否为y子集
    {x}.isdisjoint({y}) 判断x与y是否没有交集
    用>或<比较大小 判断是否是子集
    a = {1, 2, 3, 4}
    b = {2, 3}
    
    b.issubset(a)
    b.isdisjoint(a)
    a > b
    b < a
    

     

    2.7.4 常用函数和方法

    方法 含义
    add(x) 如果x不在集合中,将x增加到集合
    clear() 移除集合中所有元素
    copy() 浅拷贝
    pop() 随机返回集合中的一个元素,若集合为空则报错
    discard(x) 若x在集合中,移除x;若x不存在,不报错
    remove(x) 若x在集合中,移除x;若x不存在,报错
    x in S 判断x是否是集合S元素
    x not in S 判断x是否不是集合S元素
    函数 含义
    len() 返回集合元素个数
    a = {1, 2, 3, 4}
    a.add(5)
    a
    
    b=a.copy()        # 浅拷贝
    b
    
    3 not in b
    
    len(b)
    
  • 相关阅读:
    codeforces 980A Links and Pearls
    zoj 3640 Help Me Escape
    sgu 495 Kids and Prizes
    poj 3071 Football
    hdu 3853 LOOPS
    hdu 4035 Maze
    hdu 4405 Aeroplane chess
    poj 2096 Collecting Bugs
    scu 4444 Travel
    zoj 3870 Team Formation
  • 原文地址:https://www.cnblogs.com/1k-yang/p/12082794.html
Copyright © 2011-2022 走看看