可变与不可变类型

截止到目前为止我们已经学过很多数据类型:数字类型、字符串类型、列表类型、元祖类型。

在python中,我们对数据类型还有另外一种分类方式,我们给数据类型分为可变数据类型和不可变数据类型。在了解原理之前,我们先来看看分类情况:

可变类型 不可变类型
列表 数字
  字符串
  元组

看着上面这句话,我们来看看什么叫可变什么叫不可变

列表

>>> l = [1,2,3,4]
>>> id(l)
4392665160
>>> l[1] = 1.5
>>> l
[1, 1.5, 3, 4]
>>> id(l)
4392665160

数字

>>> a = 1
>>> id(a)
4297537952
>>> a+=1
>>> id(a)
4297537984

从内存角度看列表与数字的变与不变

字符串

#例1
>>> s = 'hello'
>>> s[1] = 'a'
Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    s[1] = 'a'
TypeError: 'str' object does not support item assignment
#例2
>>> s = 'hello'
>>> id(s)
4392917064
>>> s += ' world'
>>> s
'hello world'
>>> id(s)
4393419504

字符串也可以像列表一样使用索引操作,但是通过上例可以看出,我们不能像修改列表一样修改一个字符串的值,当我们对字符串进行拼接的时候,原理和整数一样,id值已经发生了变化,相当于变成了另外一个字符串。

元组——不允许修改

>>> t = (1,2,3,4)
>>> t[1] = 1.5
Traceback (most recent call last):
  File "<pyshell#10>", line 1, in <module>
    t[1] = 1.5
TypeError: 'tuple' object does not support item assignment

hash

假设现在要你存储一些数据如下,你会怎么存?

张三 13980593357
李四 15828662334
王老五 13409821234

[[‘张三’,13980593357][‘李四’,15828662334][‘王老五’,13409821234]]

像上面这样存行不行?

可以~现在咱们有一个需求,就是获取“王五”的电话号码,你怎么做?

遍历整个列表,找到“王五”的信息所在的列表,然后拿到王五的电话。看起来一切顺利。

但是当我们需要存储的人越来越多,这个寻找的过程就会变得非常漫长,如果我们存了5000万个人的信息,那么找人这个过程就变得像大海捞针一样了。。。有没有什么好办法能够让我们一下子就找到对应的人呢?

我们都知道数据是存储在内存里的,内存中的每一个位置都有自己的地址标示。假如我们能够将这些人名转换成数字直接存储在数字代表的内存地址中,等要找这个人的时候,直接去这个地址找人是不是就方便了?

假如对上述的联系人信息进行存储时,采用的Hash函数为:姓名的每个字的拼音开头大写字母的ASCII码之和。因此
address(张三)=ASCII(Z)+ASCII(S)=90+83=173;
address(李四)=ASCII(L)+ASCII(S)=76+83=159;
address(王老五)=ASCII(W)+ASCII(L)+ASCII(W)=87+76+87=250;

当然了,这只是一个示意图,具体的情况比这个还要复杂,还有很多复杂的因素都没有考虑进入,比如如果计算出来的hash值发生了冲突怎么办?还有现在这张图就可以看出空间上的浪费,这就需要我们在设计hash算法的时候不能像我刚刚假设的那样随意。但这已经足以向你说明hash算法的与众不同,它能为你在数据查找的过程中节省多少时间。

现在,告诉你一个好消息,你不需要关心hash值是如何计算的,因为python已经为我们设计了一套算法你只要拿来用就可以:

>>> hash("张三")
6480394008723176318
>>> hash("李四")
-114706925611844552
>>> hash("王老五")
3250319002057530081

可以被hash的内容

刚刚我们已经说过,hash值的计算过程是依据这个值的一些特征计算的,这就要求被hash的值必须固定。

可以想见如果“王老五”变成“王老六”了,计算的结果就会发生改变。

因此我们要说,坏消息是可变的数据类型是不可以被hash的,好消息是如果一个值可以hash那么说明这是一个不可变得数据类型。

不会用hash没有关系,这里你先知道什么是hash,接下来,我们要学习一种很厉害的数据类型,它就是用这种方式,让我们能够从大量数据中直接快速找到我们想要的数据。

可变,不可变类型和hash的更多相关文章

  1. 可变、不可变数据类型和hash

    一.可变和不可变数据类型 在python中,我们对数据类型除了分为数字类型.字符串类型.列表类型.元组类型.字典类型和集合类型外, 还有另外一种分类方式,我们给数据类型分为可变数据类型和不可变数据类型 ...

  2. 【redis】02string类型和hash类型

    Redis的数据类型   Redis主要分为五个数据类型,一个是string,最简单的一个数据类型,hash,list, 还有set集合,还有zset有序集合,这是咱们redis的五种基础类型, 接下 ...

  3. Redis 笔记与总结2 String 类型和 Hash 类型

    Linux 版本信息: cat /etc/issue 或cat /etc/redhat-release(Linux查看版本当前操作系统发行版信息) CentOS release 6.6 (Final) ...

  4. 02_NoSQL数据库之Redis数据库:string类型和hash类型

     Strings类型及操作 String是最简单的类型,一个key对应一个Value,String类型是二进制安全的.Redis的String可以包含任何数据,比如jpg图片或者序列化的对象. S ...

  5. 第一节: Redis之String类型和Hash类型的介绍和案例应用

    一. String类型基础 1.类型介绍 典型的Key-Value集合,如果要存实体,需要序列化成字符串,获取的时候需要反序列化一下. 2. 指令Api说明 3.常用Api说明 (1).StringS ...

  6. Redis的增删改查 c# key value类型和hash map 类型

    using Newtonsoft.Json; using StackExchange.Redis; using System; using System.Collections.Generic; us ...

  7. python 类属性 、实例属性,可变数据结构作为类属性需要注意的地方

    1.一些经典的python错误不去阅读和不重视,就会把错误的做法带入到实际项目中来,甚至造成难以排查问题. 2.有一个大笨猪,按java写观察者模式,java写得是直接在类名下声明一个实例属性(不加s ...

  8. 函数----基础,参数传递,返回类型和return语句

    一.函数基础1.形参和实参 实参是形参的初始值.第一个实参初始化第一个形参,第二个实参初始化第二个形参,以此类推.尽管实参与形参存在对应关系,但是并没有规定实参的求值顺序.编译器能以任意可行的顺序对实 ...

  9. 着重基础之—MySql Blob类型和Text类型

    着重基础之—MySql Blob类型和Text类型 在经历了几个Java项目后,遇到了一些问题,在解决问题中体会到基础需要不断的回顾与巩固. 最近做的项目中,提供给接口调用方数据同步接口,传输的数据格 ...

随机推荐

  1. Win10系列:VC++ Direct3D模板介绍1

    Visual Studio为开发Direct3D应用程序提供了便捷的模版,读者可以不必手动去新建Direct3D中所使用到的基础资源,而只需专注于图形的绘制.本小节主要为读者介绍这个模版中用于绘制图形 ...

  2. UVA 11990 `Dynamic'' Inversion CDQ分治, 归并排序, 树状数组, 尺取法, 三偏序统计 难度: 2

    题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...

  3. day4-python基础-运算符

    本章节主要说明Python的运算符.举个简单的例子 4 +5 = 9 . 例子中,4 和 5 被称为操作数,"+" 称为运算符. Python语言支持以下类型的运算符: 算术运算符 ...

  4. 前端小菜鸡使用Vue+Element笔记(二)

    记录一下在使用Vue和Element做项目时遇到过的难点... 1.在 <el-table>表格中嵌入 select下拉选择框,以及 tooltip提示框的使用 主要定义格式如红色标记代码 ...

  5. JDK(java se development kit)的构成

    1.javac(Java compiler)编译器 通过命令行输入javac命令调用Java编译器,编译Java文件的过程中,javac会检查源程序是否符合Java的语法,没有语法 问题就会将.jav ...

  6. 奇怪问题之@RequestBody问题

    在项目中使用到了@RequestBody注解:该注解的作用是获取Request请求中body中的数据:最近测试项目的时候发现调用该接口的时候直接返回状态400,当将@RequestBody注解去掉以后 ...

  7. 单字段去重 distinct 返回其他多个字段

    select a.*, group_concat(distinct b.attribute_name) from sign_contract_info a left join sign_temp_at ...

  8. windows 访问局域网共享文件

    直接在浏览器或资源管理器输入路径就OK file://10.16.73.129/FinTech/soft

  9. 设置table中的td一连串内容自动换行

    遇到一长串字母撑出了td宽度,导致整个表格错乱,如图: , 解决办法: 第一: table 加上css: table-layout: fixed;(此css属性 表示 列宽由表格宽度和列宽度设定.不会 ...

  10. 手机号的 DES-ECB 加密/解密

    前言:公司的手机号加密更换了加密方法,这次改成 DES-ECB 加密了 代码操作 # -*- coding:utf-8 -*- import base64 import json from Crypt ...