第二章 数据类型和文件操作

变量创建过程

 

首先,当我们定义了一个变量name = ‘oldboy’的时候,在内存中其实是做了这样一件事:

程序开辟了一块内存空间,将‘oldboy’存储进去,再让变量名name指向‘oldboy’所在的内存地址。如下图所示:

我们可以通过id()方法查看这个变量在内存中的地址

  1. >>> name = "oldboy"
  2. >>> id(name)
  3. 4317182304

python 解释器有自动垃圾回收机制,自动隔一段时间把没有跟变量名关联的内存数据回收

name = "wuxiping"
name = "Jack"
print(id(name))

name = "Alex"
name1 = name
print(name1)
print(id(name),id(name1))

name = "黑姑娘"
print(name1)   # 因为name1是直接指向Alex,所以name1 没变

身份运算

python 中有很多种数据类型, 查看一个数据的类型的方法是type().

判断一个数据类型是不是str, or int等,可以用身份运算符is

 

  1. >>> type(name) is str
  2. True
  3. >>>
  4. >>> type(name) is not int
  5. True

 

# 身份运算
name = "Alex"
name1 = "黑姑娘"
print(type(name1))
print(type(name1) is str)
print(type(name1) is int)
# 不能直接说 name1 is str,因为name1 是一个字符串,现在判断的是它是不是一个字符串类型!因此要先拿到它的类型
print(name1 is str)

age = 12.32
print(type(age) is not float)

 

空值None

代表什么都没有的意思,一般用在哪呢? 比如玩游戏,你要初始化一个女朋友, 需要填上姓名、年龄、身高、体重等信息, 这些信息是让玩家填的,在填之前,你要先把变量定义好,那就得存个值 ,这个值用0,1来占位不合适 ,用True,False也不合适 ,用None最合适

  1. >>> name=None
  2. >>> age=None
  3. >>> height=None
  4. >>> weight=None
  5. >>>
  6. >>> name,age,height,weight
  7. (None, None, None, None)
  8. >>>

此时可用is 运算符来判断变量是不是None

  1. >>> if name is None:
  2. ... print("你的女朋友还没起名字呢.")
  3. ...
  4. 你的女朋友还没起名字呢.

其实用==判断也行,但是不符合开发规范

  1. >>> name == None
  2. True

三元运算

显的很NB的代码写法。

# 三元运算
a = 10
b = 5
if a>15:
    c = a
else:
    c = b
print(c)
# 或者
d = a if a>15 else b
print(d)

d = 值1 if 条件A else 值2

如果条件A成立,就取左边值1,否则就取值2

细讲数据类型----列表

 

追加,数据会追加到尾部

  1. >>> names
  2. ['alex', 'jack']
  3. >>> names.append("rain")
  4. >>> names.append("eva")
  5. >>>
  6. >>> names
  7. ['alex', 'jack', 'rain', 'eva']

插入,可插入任何位置

  1. >>> names.insert(2,"黑姑娘")
  2. >>> names
  3. ['alex', 'jack', '黑姑娘', 'rain', 'eva']
  4. >>>

合并,可以把另一外列表的值合并进来

  1. >>> n2 = ["狗蛋","绿毛","鸡头"]
  2. >>> names
  3. ['alex', 'jack', '黑姑娘', 'rain', 'eva']
  4. >>> names.extend(n2)
  5. >>> names
  6. ['alex', 'jack', '黑姑娘', 'rain', 'eva', '狗蛋', '绿毛', '鸡头']

列表嵌套

  1. >>> names.insert(2,[1,2,3])
  2. >>> names
  3. ['alex', 'jack', [1, 2, 3], '黑姑娘', 'rain', 'eva', '狗蛋', '绿毛', '鸡头']
  4. >>> names[2][1]
  5. 2

 

删除操作

del 直接删

  1. >>> names
  2. ['alex', 'jack', [1, 2, 3], '黑姑娘', 'rain', 'eva', '狗蛋', '绿毛', '鸡头']
  3. >>> del names[2]
  4. >>> names
  5. ['alex', 'jack', '黑姑娘', 'rain', 'eva', '狗蛋', '绿毛', '鸡头']

pop 删

  1. >>> names
  2. ['alex', 'jack', '黑姑娘', 'rain', 'eva', '狗蛋', '绿毛', '鸡头']
  3. >>> names.pop() #默认删除最后一个元素并返回被删除的值
  4. '鸡头'
  5. >>> names
  6. ['alex', 'jack', '黑姑娘', 'rain', 'eva', '狗蛋', '绿毛']
  7. >>> help(names.pop)
  8. >>> names.pop(1) #删除指定元素
  9. 'jack'

clear 清空

  1. >>> n2
  2. ['狗蛋', '绿毛', '鸡头']
  3. >>> n2.clear()
  4. >>> n2
  5. []

修改操作

  1. >>> names
  2. ['alex', '黑姑娘', 'rain', 'eva', '狗蛋', '绿毛']
  3. >>> names[0] = "金角大王"
  4. >>> names[-1] = "银角大王"
  5. >>> names
  6. ['金角大王', '黑姑娘', 'rain', 'eva', '狗蛋', '银角大王']

查操作

  1. >>> names
  2. ['金角大王', '黑姑娘', 'rain', 'eva', '狗蛋', '银角大王', 'eva']
  3. >>>
  4. >>> names.index("eva") #返回从左开始匹配到的第一个eva的索引
  5. 3
  6. >>> names.count("eva") #返回eva的个数
  7. 2
name = ['金角大王', '黑姑娘', 'rain', 'eva', '狗蛋', '银角大王', 'eva']

# 切片,顾头不顾尾
print(name[1:4])
print(name[1:-2])
print(name[1:])  # 可取最后一个数
print(name[:5])
# 倒着切
print(name[-5:-1])
print(name[-5:])
# 步长, 允许跳着取值
print(name[0:-1:1])
print(name[0:-1:2])
print(name[0:-1:3])

# 从右往左走
print(name[-1:-5:-1])  # 步长变成负的即可

print(name[:]) # 都省略,全取
print(name[0:-1:2])
print(name[::2])

 

# 反转
name = ['金角大王', '黑姑娘', 'rain', 'eva', '狗蛋', '银角大王', 'eva']

n = "银角大王"
print(n[::-1])
name.reverse()
print(name)

# 排序
name.sort()
print(name)
# 循环列表
for i in name:
    print(i)

 细讲数据类型-元组(大部分和列表相似)

  不可修改

索引,切片,等

count,index

注意:元组本身不可变,如果元组中还包含其他可变元素,这些可变元素可以改变

>>> data 
(99, 88, 77, ['Alex', 'Jack'], 33)
>>> data[3][0] = '金角大王'
>>> data
(99, 88, 77, ['金角大王', 'Jack'], 33)

为啥呢? 因为元组只是存每个元素的内存地址,上面[‘金角大王’, ‘Jack’]这个列表本身的内存地址存在元组里确实不可变,但是这个列表包含的元素的内存地址是存在另外一块空间里的,是可变的。

 细讲数据类型-字符串

定义

字符串是一个有序的字符的集合,用于存储和表示基本的文本信息,’ ‘或’’ ‘’或’’’ ‘’’中间包含的内容称之为字符串

 反转:将步长变成-1即可

特性:

按照从左到右的顺序定义字符集合,下标从0开始顺序访问,有序

1.可以进行切片操作

2.不可变,字符串是不可变的,不能像列表一样修改其中某个元素,所有对字符串的修改操作其实都是相当于生成了一份新数据。

补充:

1.字符串的单引号和双引号都无法取消特殊字符的含义,如果想让引号内所有字符均取消特殊意义,在引号前面加r,如name=r’l\thf’

字典:

字典是Python语言中唯一的映射类型。

定义:{key1:value1,key2:value2}

特性:

1.key-value结构

2.key必须为不可变数据类型、必须唯一

3.可存放任意多个value、可修改、可以不唯一

4.无序

5.查询速度快,且不受dict的大小影响,至于为何快?我们学完hash再解释。

# coding=utf-8
# 字典:定义:{key1:value1,key2:value2}
# info = {
#     "name":"小猿圈",
#     "mission": "帮一千万极客高效学编程",
#     "website": "http://apeland.com"}
# print(info.keys())

# 创建操作
# person = {"name": "alex", 'age': 20}

# person = dict(name='seven', age=20)

# keys = [1,2,3,4,5]
# a= {}.fromkeys(keys,100)
# print(a)

# 增加
# person = {"name": "alex", 'age': 20}
# person["job"] = "Teacher"
# print(person)
# person.setdefault("salary",[1,2,3])
# print(person)
# 删除
person = {"name": "alex", 'age': 20}
# print(person)
# print(person.pop("name"))   # 删除指定键key
# print(person)
# print(person)
# del person["name"]    # 删除指定键key
# print(person)
# print(person.clear())  # 清空字典

# 修改操作
# person["name"] = "NAME"
# print(person)  # 替代原先的value值
# person1 = {"gender":"male"}
# print(person.update(person1)) # 将字典person1的键值对添加到字典person中
# print(person)

# 查操作
# print(person["name"]) # 返回字典中key对应的值,若key不存在字典中,则报错
# print(person.get("name")) # 返回字典中key对应的值,若key不在字典中,则返回default的值(default默认为None)
# print("name" in person)  # 若存在则返回True,否则返回False
# print(person.keys()) # 返回一个包含字典所有key的列表
# print(person.values()) # 返回一个包含字典所有value的列表
# print(person.items()) # 返回一个包含所有(键,值)元祖的列表

# 循环
# for i in person:
#     print(i,person[i])
# for i in person.items():
#     print(i)
# for k,v in person.items():
#     print(k,v)
# for i in person.keys():
#     print(i)
for i in person.values():
    print(i)

细讲数据类型-集合

定义

1.里面的元素不可变,代表你不能存一个list、dict 在集合里,字符串、数字、元组等不可变类型可以存

2.天生去重,在集合里没办法存重复的元素

3.无序,不像列表一样通过索引来标记在列表中的位置 ,元素是无序的,集合中的元素没有先后之分,如集合{3,4,5}和{3,5,4}算作同一个集合

基于上面的特性,我们可以用集合来干2件事,去重和关系运算

 

# 创建集合  set 增删查
a = {1,2,3,4,2,'alex',3,'rain','alex'}
print(a)
a.add(5)
print(a)
# a.add([1,2,3])
# print(a)
a.add((1,2,3))
print(a)
# 删除
a.discard(5)
# 随机删除
a.pop()
# 如果没有该元素就会报错
a.remove()
# 关系运算
s_1024 = {"佩奇","老男孩","海峰","马JJ","老村长","黑姑娘","Alex"}
s_pornhub = {"Alex","Egon","Rain","马JJ","Nick","Jack"}
print(s_1024 & s_pornhub)  # 交集, elements in both set
print(s_1024 | s_pornhub)  # 并集 or 合集
print(s_1024 - s_pornhub)  # 差集 , only in 1024
print(s_pornhub - s_1024)  # 差集,  only in pornhub
print(s_1024 ^ s_pornhub)  # 对称差集, 把脚踩2只船的人T出去
print(s_1024.intersection(s_pornhub))

 

 秒懂二进制

字符编码之文字是如何显示的

ASCII码

这张表就是计算机显示各种文字、符号的基石呀

ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。它是现今最通用的单字节编码系统,并等同于国际标准ISO/IEC 646。

 

在这里,每一位0或者1所占的空间单位为bit(比特),这是计算机中最小的表示单位

每8个bit组成一个字节,这是计算机中最小的存储单位(毕竟你是没有办法存储半个字符的)orz~

  1. bit 位,计算机中最小的表示单位
  2. 8bit = 1bytes 字节,最小的存储单位,1bytes缩写为1B
  3. 1KB=1024B
  4. 1MB=1024KB
  5. 1GB=1024MB
  6. 1TB=1024GB
  7. 1PB=1024TB
  8. 1EB=1024PB
  9. 1ZB=1024EB
  10. 1YB=1024ZB
  11. 1BB=1024YB

GBK2312   2个字节代表一个字符

 

论断句的重要性与必要性:

Unicode标准也在不断发展,但最常用的是用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要4个字节)。现代操作系统和大多数编程语言都直接支持Unicode

 

 

UTF-8

新的问题又出现了:如果统一成Unicode编码,乱码问题从此消失了。但是,如果你写的文本基本上全部是英文的话,用Unicode编码比ASCII编码需要多一倍的存储空间,由于计算机的内存比较大,并且字符串在内容中表示时也不会特别大,所以内容可以使用unicode来处理,但是存储和网络传输时一般数据都会非常多,那么增加1倍将是无法容忍的!!!

为了解决存储和网络传输的问题,出现了Unicode Transformation Format,学术名UTF,即:对unicode字符进行转换,以便于在存储和网络传输时可以节省空间!

 

    • UTF-8: 使用1、2、3、4个字节表示所有字符;优先使用1个字符、无法满足则使增加一个字节,最多4个字节。英文占1个字节、欧洲语系占2个、东亚占3个,其它及特殊字符占4个

 

    • UTF-16: 使用2、4个字节表示所有字符;优先使用2个字节,否则使用4个字节表示。

 

    • UTF-32: 使用4个字节表示所有字符;

 

总结:UTF 是为unicode编码 设计 的一种 在存储 和传输时节省空间的编码方案。

如果你要传输的文本包含大量英文字符,用UTF-8编码就能节省空间:

hash是个什么东西阅读量: 461
 

什么是哈希?

hash,一般翻译做散列、杂凑,或音译为哈希,是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间。

它其实就是一个算法,最简单的算法就是加减乘除,比方,我设计个数字算法,输入+7=输出,比如我输入1,输出为8;输入2,输出为9。

哈希算法不过是一个更为复杂的运算,它的输入可以是字符串,可以是数据,可以是任何文件,经过哈希运算后,变成一个固定长度的输出,该输出就是哈希值。但是哈希算法有一个很大的特点,就是你不能从结果推算出输入,所以又称为不可逆的算法

 

哈希特性

 

不可逆:在具备编码功能的同时,哈希算法也作为一种加密算法存在。即,你无法通过分析哈希值计算出源文件的样子,换句话说:你不可能通过观察香肠的纹理推测出猪原来的样子。

 

计算极快:20G高清电影和一个5K文本文件复杂度相同,计算量都极小,可以在0.1秒内得出结果。也就是说,不管猪有多肥,骨头多硬,做成香肠都只要眨眨眼的时间,

 

哈希的用途

 

哈希算法的不可逆特性使其在以下领域使用广泛

1.密码,我们日常使用的各种电子密码本质上都是基于hash的,你不用担心支付宝的工作人员会把你的密码泄漏给第三方,因为你的登录密码是先经过 hash+各种复杂算法得出密文后 再存进支付宝的数据库里的

2.文件完整性校验,通过对文件进行hash,得出一段hash值 ,这样文件内容以后被修改了,hash值就会变。 MD5 Hash算法的”数字指纹”特性,使它成为应用最广泛的一种文件完整性校验和(Checksum)算法,不少Unix系统有提供计算md5 checksum的命令。

3.数字签名,数字签名技术是将摘要信息用发送者的私钥加密,与原文一起传送给接收者。接收者只有用发送者的公钥才能解密被加密的摘要信息,然后用HASH函数对收到的原文产生一个摘要信息,与解密的摘要信息对比。如果相同,则说明收到的信息是完整的,在传输过程中没有被修改,否则说明信息被修改过,因此数字签名能够验证信息的完整性。

此外,hash算法在区块链领域也使用广泛。

md5加密算法

基于hash的数据类型有哪些?

Python 中基于hash的2个数据类型是dict and set , 之前说dict查询速度快,为何快? 说set天生去重,怎么做到的?其实都是利用了hash的特性,我们下面来剖析

用Python操作文件

 

 

  1. f=open(filename) # 打开文件
  2. f.write("我是野生程序员") # 写操作
  3. f.read() #读操作
  4. f.close() #保存并关闭

操作模式

 

    • r 只读模式


    • w 创建模式,若文件已存在,则覆盖旧文件


    • a 追加模式,新数据会写到文件末尾

 

posted @ 2019-07-20 21:36  aggressive2019  阅读(196)  评论(0编辑  收藏  举报