• Python(00):复杂数据类型(set、dict)


    一、集合(set):{a1,a2},可变数据类型

    集合(set)是一个无序的不重复元素序列。

    • 集合元素不重复
    • 集合元素之间无序。
    • 集合类型主要应用于:包含关系比较、数据去重
    s = {1, 2, 1, 'a'}  # 建立集合类型用 {} 元素间用逗号分隔
    print(s)  
    s = set({1,2,'a'}) # 使用set()建立集合
    print(s) 
    s = set() # 建立空集合,建必须使用set() ,而不是 { },因为 { } 是用来创建一个空字典。
    print(s) 

      set(x):将其他类型变量x转变为集合类型。

      s = set('hello') 
      print(s)  # {'h', 'l', 'o', 'e'}

      ls = ["p", "p", "y", "y",123]
      s = set(ls)   # 利用了集合无重复元素的特

      二、集合推导式

      #列表推导式
      a = [x for x in 'abracadabra' if x not in 'abc']
      print(a) # ['r', 'd', 'r']
      
      #元组不支持,为生成器对象
      a = (x for x in 'abracadabra' if x not in 'abc')
      print(a) # <generator object <genexpr> at 0x0000000002147EB0>
      
      #集合推导式
      a = {x for x in 'abracadabra' if x not in 'abc'}
      print(a) # {'r', 'd'}

      三、集合的基本操作

      s = {1, 2, 'a'} 
      print(len(s)) #1、长度len ;len(s): 3
      s = {1, 2, 'a'}
      print(1 in s) # 2、成员运算in和not in ;True

      pythoners = {'jason', 'nick', 'tank', 'sean'}
      linuxers = {'nick', 'egon', 'kevin'}
      javers = {'nick', 'egon', 'kevin'}
      print(pythoners == linuxers) # ==:全等 False
      print(javers == linuxers) # True

      037-集合类型及操作-01.jpg?x-oss-process=style/watermark

      pythoners = {'jason', 'nick', 'tank', 'sean'}
      linuxers = {'nick', 'egon', 'kevin'}
      print(pythoners | linuxers) # |:union()并集  {'egon', 'tank', 'kevin', 'jason', 'nick', 'sean'}
      print(pythoners.union(linuxers)) #{'egon', 'tank', 'kevin', 'jason', 'nick', 'sean'}
      
      pythoners = {'jason', 'nick', 'tank', 'sean'}
      linuxers = {'nick', 'egon', 'kevin'}
      print(pythoners & linuxers) #   &:intersection()交集  {'nick'}
      print(pythoners.intersection(linuxers)}) {'nick'}
      
      pythoners = {'jason', 'nick', 'tank', 'sean'}
      linuxers = {'nick', 'egon', 'kevin'}
      print(pythoners - linuxers) #  -:difference()差集  {'tank', 'jason', 'sean'}
      print(pythoners.difference(linuxers)) #{'tank', 'jason', 'sean'}
      
      pythoners = {'jason', 'nick', 'tank', 'sean'}
      linuxers = {'nick', 'egon', 'kevin'}
      print(pythoners ^ linuxers) # ^:symmetric_difference()补集  {'egon', 'tank', 'kevin', 'jason', 'sean'}
      print(pythoners.symmetric_difference(linuxers))# {'egon', 'tank', 'kevin', 'jason', 'sean'}

      >、>=:父集:issuperset()

      pythoners = {'jason', 'nick', 'tank', 'sean'}
      linuxers = {'nick', 'egon', 'kevin'}
      javaers = {'jason', 'nick'}
      
      print(pythoners > linuxers) # False
      print(pythoners >= linuxers) # False
      print(pythoners >= javaers) # True
      print(pythoners.issuperset(javaers)) #True

      <、<=:子集:issubset()

      pythoners = {'jason', 'nick', 'tank', 'sean'}
      linuxers = {'nick', 'egon', 'kevin'}
      javaers = {'jason', 'nick'}
      
      print(pythoners < linuxers) # False
      print(pythoners <= linuxers) #False
      print(javaers.issubset(javaers)) #True

      四、集合相关函数

      s = {1, 2, 'a'}
      s.add(3) # add(x):如果x不在集合S中,将x增加到S
      print(s) #{1, 2, 3, 'a'}
      
      thisset = set(("Google", "Runoob", "Taobao"))
      thisset.update({1,3}) # update( x ):添加元素,且参数可以是列表,元组,字典等,
      print(thisset) # {1, 3, 'Google', 'Taobao', 'Runoob'}
      
      thisset.update([1,4],[5,6])  
      print(thisset) # {1, 3, 4, 5, 6, 'Google', 'Taobao', 'Runoob'}
      
      
      # 注意: set.update( "字符串" ) 与 s.update( {"字符串"} ) 含义不同:
      thisset = set(("Google", "Runoob", "Taobao"))
      print(thisset) # {'Google', 'Runoob', 'Taobao'}
      
      thisset.update( {"Facebook"} ) # s.update( {"字符串"} ) 将字符串添加到集合中,有重复的会忽略。 
      print(thisset) # {'Google', 'Runoob', 'Taobao', 'Facebook'}
      
      thisset.update( "Yahoo" ) # s.update( "字符串" ) 将字符串拆分单个字符后,然后再一个个添加到集合中,有重复的会忽略。
      print(thisset) # {'a', 'Facebook', 'h', 'Runoob', 'o', 'Taobao', 'Google', 'Y'}
      
      
      s = {1, 2, 'a'}
      s.remove(1) # remove(x):移除S中元素x,如果x不在集合S中,产生KeyError异常
      print(s) #{2, 'a'}
      
      s.clear() # clear():清空集合
      
      s = {1, 2, 'a'}
      # s.remove(3)  # 报错
      s.discard(3) # discard(x):移除S中元素x,如果x不在集合S中,不报错
      print(s) #{1, 2, 'a'}
      
      pythoners = {'jason', 'nick', 'tank', 'sean'}
      linuxers = {'nick', 'egon', 'kevin'}
      pythoners.difference_update(linuxers) # difference_update():移除集合中的元素,该元素在指定的集合也存在。
      print(pythoners) #{'tank', 'jason', 'sean'}
      
      pythoners = {'jason', 'nick', 'tank', 'sean'}
      linuxers = {'nick', 'egon', 'kevin'}
      pythoners.isdisjoint(linuxers) # isdisjoint():判断两个集合是否包含相同的元素,如果没有返回 True,否则返回 False。
      print(pythoners.isdisjoint(linuxers)) # False

      五、字典(dict):{a1:b1,a2:b2},可变数据类型

      用来存取多个值,按照key:value的方式存值,取的时候可以通过key而非索引去取值,key对value具有描述性的作用。

      存放数据的种类各种各样并且数据较多的时候可以使用字典。

      在{}内用逗号分隔开多个元素,每一个元素都是key: value的格式,其中value是任意格式的数据类型,key由于具有描述性的作用,所以key通常是字符串类型。

      • 键必须是唯一的。
      • 值可以取任何数据类型,但键必须是不可变的,如字符串,数字或元组。

      创建空字典必须使用 { }。

      user_info = {'name': 'nick', 'gender': 'male', 'age': 19, 'company_info': ['oldboy', 'shanghai', 50]}
      
      print(id(user_info)) # 4396183344
      print(type(user_info)) # <class 'dict'>
      print(user_info) # {'name': 'nick', 'gender': 'male', 'age': 19, 'company_info': ['oldboy', 'shanghai', 50]}

      1、构造函数 dict()

      1、从键值对元组列表中构建字典。

      dic = dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
      print(dic)
      # {'sape': 4139, 'guido': 4127, 'jack': 4098}

      2、使用关键字参数指定键值

      dic =dict(a=1, b=2, c=3)
      print(dic)  # {'a': 1, 'b': 2, 'c': 3}

      字典取值方式不再依赖于索引,而是依赖于key,通过[key]即可获取key对应的value值。可存可取

      字典套列表

      user_info = {'name': 'nick', 'gender': 'male', 'age': 19, 'company_info': ['oldboy', 'shanghai', 50] }
      print(user_info['name']) #nick
      
      user_info['name'])=’a’
      print(user_info['company_info'][0])#oldboy

      字典套字典

      user_info = {'name': 'nick', 'gender': 'male', 'age': 19, 'company_info': {'c_name': 'oldboy', 'c_addr': 'shanghai', 'c_num_of_employee': 50} }
      
      print(user_info['name'])#nick
      print(user_info['company_info']['c_name'])#oldboy

      2、转成字典类型

      zip()解压缩方法:

      keys = ['name', 'age', 'gender']
      values = ['nick', 19, 'male']
      
      res = zip(keys, values) #压缩
      print(res)  # <zip object at 0x0000000002233540>
      
      info_dict = {k: v for k, v in res} #解压缩print(info_dict)  # {'name': 'nick', 'age': 19, 'gender': 'male'}

      通过解压缩函数生成一个字典返回:

      info_dict = {'name': 'nick', 'age': 19, 'gender': 'male'}
      print(info_dict.keys())  # dict_keys(['name', 'age', 'gender'])
      print(info_dict.values())  # dict_values(['nick', 19, 'male'])
      
      res = zip(info_dict.keys(), info_dict.values())
      print(res)  # <zip object at 0x00000000026939C0>
      
      info_dict = {k: v for k, v in res}
      print(info_dict)  # {'name': 'nick', 'age': 19, 'gender': 'male'}

      六、字典推导式

      字典推导式可以用来创建任意键和值的字典:

      dic={ x: x**2 for x in (2, 4, 6)}
      print(dic)
      # {2: 4, 4: 16, 6: 36}
      
      print( {i: i**2 for i in range(10)} )
      {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

      举例:

      #例子一:大小写key合并
      mcase = {'a': 10, 'b': 34, 'A': 7, 'Z': 3}
      mcase_frequency = {k.lower(): mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0)  for k in mcase.keys()  if k.lower() in ['a','b'] }
      print mcase_frequency#  Output: {'a': 17, 'b': 34}
      
      #例子二:快速更换key和value
      mcase = {'a': 10, 'b': 34}
      mcase_frequency = {v: k for k, v in mcase.items()}
      print mcase_frequency
      #  Output: {10: 'a', 34: 'b'}

      七、字典的基本操作

      dic = {'a': 1, 'b': 2}
      print(len(dic)) # len:长度; 2
      
      dic = {'a': 1, 'b': 2}
      print('a' in dic)  #  in和not in:如果键在字典dict里返回true,否则返回false ;True
      print(1 in dic)  # False
      
      dic = {'a': 1, 'b': 2}
      print(dic.keys())  # dict_keys(['a', 'b']) keys():返回一个迭代器,可以使用 list() 来转换为列表
      print(dic.values())  # dict_values([1, 2])  values():返回一个迭代器,可以使用 list() 来转换为列表
      print(dic.items())  # dict_items([('a', 1), ('b', 2)]) items():以列表返回可遍历的(键, 值) 元组数组
      
      
      # dic是无序的
      dic = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
      for k, v in dic.items(): # for循环 ; items可以换成keys()、values() print(k, v)

      1、遍历技巧

      1、在序列中遍历时,索引位置和对应值可以使用 enumerate() 函数同时得到:

      for i, v in enumerate(['tic', 'tac', 'toe']):
          print(i, v)
      # 0 tic
      # 1 tac
      # 2 toe

      2、同时遍历两个或更多的序列,可以使用 zip() 组合:

      questions = ['name', 'quest', 'favorite color']
      answers = ['lancelot', 'the holy grail', 'blue']
      for q, a in zip(questions, answers):
          print('What is your {0}?  It is {1}.'.format(q, a))
      # What is your name?  It is lancelot.
      # What is your quest?  It is the holy grail.
      # What is your favorite color?  It is blue.

      3、要反向遍历一个序列,首先指定这个序列,然后调用 reversed() 函数:

      for i in reversed(range(1, 10, 2)):
          print(i, end=' ')
      # 9 7 5 3 1

      4、要按顺序遍历一个序列,使用 sorted() 函数返回一个已排序的序列,并不修改原值:

      basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
      for f in sorted(set(basket)):
          print(f)
      # apple
      # banana
      # orange
      # pear

      6、实例

      统计s='hello tank tank say hello sb sb'中每个单词的个数

      结果如:{'hello': 2, 'tank': 2, 'say': 1, 'sb': 2}

      s='hello tank tank say hello sb sb'
      l=s.split()
      
      dic={}
      for item in l:
          if item in dic:
              dic[item]+=1
      
          else:
              dic[item]=1
      print(dic)

      八、字典相关函数

      dic = {'a': 1, 'b': 2}
      del dic['a'] # 删除键 Key
      print(dic.get('a'))  # get(key, default=None)返回指定键的值,如果值不在字典中返回default值 ;None
      
      dic = {'a': 1, 'b': 2}
      dic.pop('a')  # pop(key[,default]):删除字典给定键 key 所对应的值,返回值为被删除的值。key值必须给出。 否则,返回default值。
      
      print(dic.pop('b'))  # 2
      print(dic.get('a')) 
      dic = {'a': 1, 'b': 2}
      print(dic.popitem())  #('b', 2),随机返回并删除字典中的一对键和值(一般删除末尾对)。
      
      dict.clear() # 清空字典
      
      dic = {'a': 1, 'b': 2}
      
      print(dic.setdefault('a', 3))  #  setdefault(key, default=None):和get()类似, 但如果键不存在于字典中,将会添加键并将值设为default ;1
      print(dic)  # {'a': 1, 'b': 2}
      print(dic.setdefault('c', 3))  # 3
      print(dic)  # {'a': 1, 'b': 2, 'c': 3}
      
      dic1 = {'a': 1, 'b': 2}
      dic2 = {'c': 3}
      dic1.update(dic2) # update(dict2):把字典dict2的键/值对更新到dict里
      print(dic1)  # {'a': 1, 'b': 2, 'c': 3}
      
      dic = dict.fromkeys(['name', 'age', 'sex'], None) # fromkeys(seq[, value]):创建一个新字典,以序列seq中元素做字典的键,val为字典所有键对应的初始值
      print(dic)  # {'name': None, 'age': None, 'sex': None}

      三、可变与不可变类型

      1、不可变的数据类型:数字,字符串,元组、bool,None

      不可变类型 没有提供修改对象自身的方法,对数据进行操作时,id会发生改变(重新分配地址)。

      a = "hello"   #定义一个字符串的变量
      print(id(a))  #第一次的地址
      print(a)      #a = hello
      a = a.upper() # 单纯的a.upper() 执行过后,无法存储到a本身,必须得重新赋值给a  换句话说,a在被upper之后,重新指向了一个新的地址
      print(id(a))  #第二次的地址
      print(a)

      第一段代码执行结果:

      clipboard.png

      2、可变数据类型:列表,字典,集合

      可变类型提供了修改自身这些方法,对数据进行操作 ,id不会发生改变(使用原来的地址)。

      b = [11,22,33,44,55]  #定义一个列表的变量
      print(id(b))          #第一次的地址
      print(b)              #b = [11,22,33,44,55]
      b.append(99)          #单纯的b.append()执行过后,不需要存储到b,因为b已经被更改
      print(id(b))          #检查第一次的地址
      print(b)              #发现在第一次地址当中,b已经改变

      第二段代码执行结果:

      clipboard.png

      四、对象深浅拷贝

      1、拷贝(赋值)

      如果l2是l1的拷贝对象,则l1内部的任何数据类型的元素变化,则l2内部的元素也会跟着改变,因为可变类型值变id不变。

      l1 = ['a', 'b', 'c', ['d', 'e', 'f']]
      l2 = l1
      
      l1.append('g')
      
      print(l1) #['a', 'b', 'c', ['d', 'e', 'f'], 'g']
      print(l2) #['a', 'b', 'c', ['d', 'e', 'f'], 'g']

      2、浅拷贝(copy

      如果l2是l1的浅拷贝对象,则l1内的不可变元素发生了改变,l2不变;如果l1内的可变元素发生了改变,则l2会跟着改变。

      import copy
      
      l1 = ['a', 'b', 'c', ['d', 'e', 'f']]
      l2 = copy.copy(l1)
      
      l1.append('g')
      
      print(l1) #['a', 'b', 'c', ['d', 'e', 'f'], 'g']
      print(l2) #['a', 'b', 'c', ['d', 'e', 'f']]
      l1[3].append('g')
      
      print(l1) #['a', 'b', 'c', ['d', 'e', 'f', 'g'], 'g']
      print(l2) #['a', 'b', 'c', ['d', 'e', 'f', 'g']]

      3、深拷贝(deepcopy

      如果l2是l1的深拷贝对象,则l1内的不可变元素发生了改变,l2不变;如果l1内的可变元素发生了改变,l2也不会变,即l2永远不会因为l1的变化而变化。

      import copy
      
      l1 = ['a', 'b', 'c', ['d', 'e', 'f']]
      l2 = copy.deepcopy(l1)
      
      l1.append('g')
      
      print(l1) #['a', 'b', 'c', ['d', 'e', 'f'], 'g']
      print(l2) #['a', 'b', 'c', ['d', 'e', 'f']]
      
      l1[3].append('g')
      
      print(l1) #['a', 'b', 'c', ['d', 'e', 'f', 'g'], 'g']
      print(l2) #['a', 'b', 'c', ['d', 'e', 'f']]
    • 相关阅读:
      Visual Studio 2005 Starter Kits
      怎样去做才是朋友?
      C#读写日志文本文件
      [文摘20080707]马云追加投资20亿 淘宝首定10年超沃尔玛目标
      [转]在WinForm应用程序中实现自动升级
      [转]官方Flash CS3简体中文帮助文档下载,AS3.0简体中文帮助文档下载
      [引]MySQL INNODB类型表的外键关联设置
      [转]winfrom让弹出的MessageBox在指定时间内自动销毁
      生活开心一笑 之 "我家半"与"QQ病毒"
      [English20080721]疯狂英语365句
    • 原文地址:https://www.cnblogs.com/springsnow/p/12620248.html
    Copyright © 2020-2023  润新知