zoukankan      html  css  js  c++  java
  • Python基础数据类型之集合以及其他和深浅copy

    一、基础数据类型汇总补充

    list  在循环一个列表时,最好不要删除列表中的元素,这样会使索引发生改变,从而报错(可以从后向前循环删除,这样不会改变未删元素的索引)。

     错误示范:

    lis = [11,22,33,44,55]
    for i in range(len(lis)):
        print(i)       # i = 0              i = 1               i = 2
        del lis[i]
        print(lis)  #  [11,22,33,44,55]   [22, 44, 55]          [22, 44]

    lis = [11,22,33,44,55]

    取一个新的列表 lis = [11,33,55]

    #第一种
    lis = lis[::2]
    print(lis)
    
    #第二种
    l1 = []
    for i in lis:
        if lis.index(i) % 2 == 0:
            l1.append(i)
    lis = l1
    print(lis)

    第三种,从后向前删除

    lis = [11,22,33,44,55]
    for i in range(len(lis)-1,-1,-1):
        if i % 2 == 1:
            print(i)
            del lis[i]
            print(lis)
    print(lis)
    fromkeys
    dic = dict.fromkeys([1,2,3],'春哥')
    print(dic)                                      #{1: '春哥', 2: '春哥', 3: '春哥'}
    dic = dict.fromkeys([1,2,3],[])
    print(dic)                                       # {1: [], 2: [], 3: []}
    dic[1].append('袁姐')
    print(dic)                                       #{1: ['袁姐'], 2: ['袁姐'], 3: ['袁姐']}
    dic[2].extend('二哥')
    print(dic)                                        #{1: ['袁姐', '', ''], 2: ['袁姐', '', ''], 3: ['袁姐', '', '']}

          fromkeys(x,y)   建成一个新字典,分别把y做值匹配给y,y做键,在这个字典里,键是不相同的,但是值都是一个,那就是y,x可以是可迭代的列表等。

    不要在循环中去删除字典中的键值对,字典是无序的,循环是有序的,一旦字典的长度改变,就没法循环,会报错。

    错误示范:

    dic = {'k1':'v1','k2':'v2','a3':'v3'}    #   只保留键里不含k的键值对字典
    for i in dic:
        if 'k' in i:
            del dic[i]
    print(dic)

    正确:

    l = []
    for i in dic:
        if 'k' in i:
            l.append(i)
    for i in l:
        del dic[i]
    print(dic)

     二、集合

    集合:集合是无序的,不重复的数据集合,它里面的元素是可哈希的(不可变类型),但是集合本身是不可哈希(所以集合做不了字典的键)的。以下是集合最重要的两点:

      去重,把一个列表变成集合,就自动去重了。

      关系测试,测试两组数据之前的交集、差集、并集等关系。

    set1 = set({1,2,3})
    set2 = {1,2,3,[2,3],{'name':'alex'}}  # 错的
    print(set1)
    print(set2)

     集合里的元素必须是不可变类型的,list和字典都是可变的。

    集合的增:

    set1 = {'alex','wusir','ritian','egon','barry',}
    #增
    #add
    set1.add('女神')
    print(set1)
    #update
    set1.update('abc')       #迭代增加
    print(set1)

    删除:

    set1 = {'alex','wusir','ritian','egon','barry'}
    set1.pop()  # 随机删除
    print(set1.pop())  # 有返回值
    print(set1)
    
    set1.remove('alex')  # 按元素删除
    print(set1)
    
    clear set()
    set1.clear()
    print(set1)  # set()     清空集合
    
    del set1
    print(set1)              #删除集合

    集合不能改

    查:只有一种,就是for循环查询

    set1 = {'alex','wusir','ritian','egon','barry'}
    for i in set1:
        print(i)

    交集。(&  或者 intersection)

    set1 = {1,2,3,4,5}
    set2 = {4,5,6,7,8}
    print(set1 & set2)  # {4, 5}
    print(set1.intersection(set2))  # {4, 5}

    并集。(| 或者 union)

    set1 = {1,2,3,4,5}
    set2 = {4,5,6,7,8}
    print(set1 | set2)  # {1, 2, 3, 4, 5, 6, 7}
    print(set2.union(set1))  # {1, 2, 3, 4, 5, 6, 7}

    差集。(- 或者 difference)

    set1 = {1,2,3,4,5}
    set2 = {4,5,6,7,8}
    print(set1 - set2)  # {1, 2, 3}
    print(set1.difference(set2))  # {1, 2, 3}

    反交集。 (^ 或者 symmetric_difference)

    set1 = {1,2,3,4,5}
    set2 = {4,5,6,7,8}
    print(set1 ^ set2)  # {1, 2, 3, 6, 7, 8}
    print(set1.symmetric_difference(set2))  # {1, 2, 3, 6, 7, 8}

    子集与超集

    set1 = {1,2,3}
    set2 = {1,2,3,4,5,6}
    
    print(set1 < set2)
    print(set1.issubset(set2))  # 这两个相同,都是说明set1是set2子集。
    
    print(set2 > set1)
    print(set2.issuperset(set1))  # 这两个相同,都是说明set2是set1超集。

    frozenset不可变集合,让集合变成不可变类型。

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

     去重

    li = [1,2,33,33,2,1,4,5,6,6]
    set1 = set(li)
    print(set1)
    li = list(set1)
    print(li)
    s1 = {1,2,3}
    print(s1,type(s1))

     三、深浅copy

    赋值运算

    l1 = [1,2,3]
    l2 = l1
    l1.append('a')
    print(l1,l2)                    #值相同
    print(id(l1),id(l2))             #内存地址也相同,改变一个,另一个也会改变

    对于赋值运算来说,l1与l2指向的是同一个内存地址,所以他们是完全一样的。

    浅copy

    l1 = [1,2,3]
    l2 = l1.copy()
    print(l1,l2)
    print(id(l1),id(l2))
    l2.append('a')
    print(l1,l2)
    
    l1 = [1,2,[4,5,6],3]
    l2 = l1.copy()
    
    print(l1,id(l1))
    print(l2,id(l2))
    l1.append('a')
    print(l1,l2)
    l1[2].append('a')
    print(l1,l2)
    print(id(l1[2]))
    print(id(l2[2]))

     对于浅copy来说,第一层创建的是新的内存地址,而从第二层开始,指向的都是同一个内存地址,所以,对于第二层以及更深的层数来说,保持一致性。

    所以对于copy来说,改变其中一个的第一层,另一个变量是不会变的,但是从二层开始会同时改变。

    深deepcopy 

    import copy

    l1 = [1,2,[4,5,6],3]
    l2 = copy.deepcopy(l1)
    print(l1,id(l1))
    print(l2,id(l2))
    l1[2].append('a')
    print(l1,l2)

    对于深copy来说,两个是完全独立的,改变任意一个的任何元素(无论多少层),另一个绝对不改变。

    四、enumerate

    enumerate:枚举,对于一个可迭代的(iterable)/可遍历的对象(如列表、字符串),enumerate将其组成一个索引序列,利用它可以同时获得索引和值。

    li = ['alex','银角','女神','egon','太白']
    for i in enumerate(li):
        print(i)
    for index,name in enumerate(li,1):
        print(index,name)
    for index, name in enumerate(li, 100):  # 起始位置默认是0,可更改
        print(index, name)
  • 相关阅读:
    王道考研复习-操作系统-进程管理(二)
    王道考研复习-操作系统-计算机系统概述(一)
    Understanding Undefined Behavior
    iOS开发需要掌握的命令
    LLDB命令速查
    Flutter简介
    poj 2115 C Looooops 扩展欧几里得算法
    poj 2635 The Embarrassed Cryptographer ??/Java??(???)
    poj 3292 Semi-prime H-numbers 筛素数(简单题)
    poj 1019 Number Sequence 数学
  • 原文地址:https://www.cnblogs.com/DI-DIAO/p/8086024.html
Copyright © 2011-2022 走看看