使用dict和set

Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。

举个例子,假设要根据同学的名字查找对应的成绩,如果用list实现,需要两个list:

names=['Micheal','boy','tracy']
scores=[,,]

给定一个名字,要查找对应的成绩,就先要在names中找到对应的位置,再从scores取出对应的成绩,list越长,耗时越长。

如果用dict实现,只需要一个“名字”-“成绩”的对照表,直接根据名字查找成绩,无论这个表有多大,查找速度都不会变慢。用Python写一个dict如下:

>>> d={'lida':,'xiaoming':,'xiaohong':}
>>> d['xiaoming']

为什么dict查找速度这么快?因为dict的实现原理和查字典是一样的。假设字典包含了1万个汉字,我们要查某一个字,一个办法是把字典从第一页往后翻,直到找到我们想要的字为止,这种方法就是在list中查找元素的方法,list越大,查找越慢。

第二种方法是先在字典的索引表里(比如部首表)查这个字对应的页码,然后直接翻到该页,找到这个字,无论找哪个字,这种查找速度都非常快,不会随着字典大小的增加而变慢。

dict就是第二种实现方式,给定一个名字,比如'Michael',dict在内部就可以直接计算出Michael对应的存放成绩的“页码”,也就是95这个数字存放的内存地址,直接取出来,所以速度非常快。

你可以猜到,这种key-value存储方式,在放进去的时候,必须根据key算出value的存放位置,这样,取的时候才能根据key直接拿到value。

把数据放入dict的方法,除了初始化时指定外,还可以通过key放入:

>>> d['lubenwei']=
>>> d
{'lida': , 'xiaoming': , 'xiaohong': , 'lubenwei': }

由于一个key只能对应一个value,所以,多次对一个key放入value,后面的值会把前面的值冲掉:

>>> d['xiaoming']=
>>> d
{'lida': , 'xiaoming': , 'xiaohong': , 'lubenwei': }

如果key不存在,dict就会报错:

>>> d['lidas']
Traceback (most recent call last):
File "<pyshell#9>", line , in <module>
d['lidas']
KeyError: 'lidas'

要避免key不存在的错误,有两种办法,一是通过in判断key是否存在:

>>> 'xiaoming' in d
True

二是通过dict提供的get方法,如果key不存在,可以返回None,或者自己指定的value:

>>> d.get('xiaoming')

>>> d.get('xiaming',)

注意:返回None的时候Python的交互式命令行不显示结果。

要删除一个key,用pop(key)方法,对应的value也会从dict中删除

>>> d.pop('xiaoming')

>>> d
{'lida': , 'xiaohong': , 'lubenwei': }

请务必注意,dict内部存放的顺序和key放入的顺序是没有关系的。

和list比较,dict有以下几个特点:

  1. 查找和插入的速度极快,不会随着key的增加而增加;
  2. 需要占用大量的内存,内存浪费多。

而list相反:

  1. 查找和插入的时间随着元素的增加而增加;
  2. 占用空间小,浪费内存很少。

所以,dict是用空间来换取时间的一种方法。

dict可以用在需要高速查找的很多地方,在Python代码中几乎无处不在,正确使用dict非常重要,需要牢记的第一条就是dict的key必须是不可变对象

这是因为dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict内部就完全混乱了。这个通过key计算位置的算法称为哈希算法(Hash)。

要保证hash的正确性,作为key的对象就不能变。在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。而list是可变的,就不能作为key:

>>> key = [, , ]
>>> d[key] = 'a list'
Traceback (most recent call last):
File "<stdin>", line , in <module>
TypeError: unhashable type: 'list'

set

set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。

要创建一个set,需要提供一个list作为输入集合:

>>> s=set([,,])
>>> s
{, , }

注意,传入的参数[1, 2, 3]是一个list,而显示的set([1, 2, 3])只是告诉你这个set内部有1,2,3这3个元素,显示的[]不表示这是一个list。

重复元素在set中自动被过滤:

>>> s=set([,,,,])
>>> s
{, , }

通过add(key)方法可以添加元素到set中,可以重复添加,但不会有效果:

>>> s.add()
>>> s
{, , , }

通过remove(key)方法可以删除元素:

>>> s.remove()
>>> s
{, , }

set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集、并集等操作:

>>> s1 = set([, , ])
>>> s2 = set([, , ])
>>> s1 & s2
set([, ])
>>> s1 | s2
set([, , , ])

不知道为什么这里我的python运行不成功

set和dict的唯一区别仅在于没有存储对应的value,但是,set的原理和dict一样,所以,同样不可以放入可变对象,因为无法判断两个可变对象是否相等,也就无法保证set内部“不会有重复元素”。试试把list放入set,看看是否会报错。

,只要写sort(a,a+)就行了,默认的排序方式是升序。
>>> a=['c','b','a']
>>> a.sort()
>>> a
['a', 'b', 'c']

而对于不可变对象,比如str,对str进行操作呢:

>>> a='abv'
>>> a.replace('a','李达')
'李达bv'
>>> a
'abv'

虽然字符串有个replace()方法,也确实变出了'Abc',但变量a最后仍是'abc',应该怎么理解呢?

我们先把代码改成下面这样:


>>> b=a.replace('v','李达')
>>> b
'ab李达'
>>> a
'abv'

要始终牢记的是,a是变量,而'abc'才是字符串对象!有些时候,我们经常说,对象a的内容是'abc',但其实是指,a本身是一个变量,它指向的对象的内容才是'abc'

当我们调用a.replace('a', 'A')时,实际上调用方法replace是作用在字符串对象'abc'上的,而这个方法虽然名字叫replace,但却没有改变字符串'abc'的内容。相反,replace方法创建了一个新字符串'Abc'并返回,如果我们用变量b指向该新字符串,就容易理解了,变量a仍指向原有的字符串'abc',但变量b却指向新字符串'Abc'了:

所以,对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新的对象并返回,这样,就保证了不可变对象本身永远是不可变的。

小结

使用key-value存储结构的dict在Python中非常有用,选择不可变对象作为key很重要,最常用的key是字符串。

tuple虽然是不变对象,但试试把(1, 2, 3)(1, [2, 3])放入dict或set中,并解释结果。

切记 少就是多 慢就是快

python学习之路(6)的更多相关文章

  1. python学习之路-day2-pyth基础2

    一.        模块初识 Python的强大之处在于他有非常丰富和强大的标准库和第三方库,第三方库存放位置:site-packages sys模块简介 导入模块 import sys 3 sys模 ...

  2. Python学习之路-Day2-Python基础3

    Python学习之路第三天 学习内容: 1.文件操作 2.字符转编码操作 3.函数介绍 4.递归 5.函数式编程 1.文件操作 打印到屏幕 最简单的输出方法是用print语句,你可以给它传递零个或多个 ...

  3. Python学习之路-Day2-Python基础2

    Python学习之路第二天 学习内容: 1.模块初识 2.pyc是什么 3.python数据类型 4.数据运算 5.bytes/str之别 6.列表 7.元组 8.字典 9.字符串常用操作 1.模块初 ...

  4. Python学习之路-Day1-Python基础

    学习python的过程: 在茫茫的编程语言中我选择了python,因为感觉python很强大,能用到很多领域.我自己也学过一些编程语言,比如:C,java,php,html,css等.但是我感觉自己都 ...

  5. python学习之路网络编程篇(第四篇)

    python学习之路网络编程篇(第四篇) 内容待补充

  6. Python学习之路【第一篇】-Python简介和基础入门

    1.Python简介 1.1 Python是什么 相信混迹IT界的很多朋友都知道,Python是近年来最火的一个热点,没有之一.从性质上来讲它和我们熟知的C.java.php等没有什么本质的区别,也是 ...

  7. python 学习之路开始了

    python 学习之路开始了.....记录点点滴滴....

  8. python学习之路,2018.8.9

    python学习之路,2018.8.9, 学习是一个长期坚持的过程,加油吧,少年!

  9. Python学习之路——pycharm的第一个项目

    Python学习之路——pycharm的第一个项目 简介: 上文中已经介绍如何安装Pycharm已经环境变量的配置.现在软件已经安装成功,现在就开始动手做第一个Python项目.第一个“Hello W ...

  10. python学习之路------你想要的都在这里了

    python学习之路------你想要的都在这里了 (根据自己的学习进度后期不断更新哟!!!) 一.python基础 1.python基础--python基本知识.七大数据类型等 2.python基础 ...

随机推荐

  1. 在Linux中,没有文件创建时间的概念。只有文件的访问时间、修改时间、状态改变时间

    在Linux中,没有文件创建时间的概念.只有文件的访问时间.修改时间.状态改变时间.也就是说不能知道文件的创建时间.但如果文件创建后就没有修改过,修改时间=创建时间:如果文件创建后,状态就没有改变过, ...

  2. 第四章 子查询 T-SQL语言基础

    子查询 SQL支持在查询语句中编写查询,或者嵌套其他查询. 最外层查询的结果集会返回给调用者,称为外部查询. 内部查询的结果是供外部查询使用的,也称为子查询. 子查询可以分为独立子查询和相关子查询.独 ...

  3. js中自然日的计算

    需求:前端取后端返回的时间与当前时间进行比较展示,展示规则: 1.返回的时间跟当前时间同年同月同日 显示 今天 2.返回的时间与当前时间相差在7天以内 显示 某天前 3.返回的时间与当前时间相差大于7 ...

  4. 第六篇 CSS样式 背景、背景图、文本、链接

    元素背景.文本(字体)样式.链接 这里我们只学习常用的一些,更多的扩展就要同学们自己去了解,或者下方评论. 这里我们为了简便,用的是CSS的内嵌形式.   元素背景: 我们写模块的时候,有的时候为了区 ...

  5. MyCat配置简述以及mycat全局ID

    Mycat可以直接下载解压,简单配置后可以使用,主要配置项如下: 1. log4j2.xml:配置MyCat日志,包括位置,格式,单个文件大小 2. rule.xml: 配置分片规则 3. schem ...

  6. json字符串与json对象的转换

    JSON(JavaScript Object Notation)格式是开发中较为常见的数据格式,优点是轻量,便于理解和解析生成.JSON对象是一个无序的键值对集合,以 { } 为开头和结尾,键与键之间 ...

  7. centos 7 搭建 LNMP ( Linux+Nginx+MySQL+PHP )

    操作系统 | CentOS Linux release 7.6.1810 (Core) [root@localhost ~# cat /etc/redhat-release CentOS Linux ...

  8. 《python解释器源码剖析》第0章--python的架构与编译python

    本系列是以陈儒先生的<python源码剖析>为学习素材,所记录的学习内容.不同的是陈儒先生的<python源码剖析>所剖析的是python2.5,本系列对应的是python3. ...

  9. deep_learning_Function_tensorflow_random_normal_initializer

    函数原型:tf.random_normal_initializer(mean=0.0, stddev=1.0, seed=None, dtype=tf.float32) 返回一个生成具有正态分布的张量 ...

  10. CentOS 7 安装 gcc 4.1.2

    CentOS 7 安装 gcc 4.1.2 0. 参考 在centOS7.2上编译gcc4.1.2 1. 安装了编译所需 yum groupinstall "Development Tool ...