随机数
import random
# random 实际上是伪随机数
# 返回随机生成的一个实数,它在[0,1)范围内。
print(random.random())
# 随机浮点数[2, 3) 包括2
print(random.uniform(2, 3))
# 随机整数 [2,3,4] 注意左右数字都包含
print(random.randint(2, 4))
# shuffle 打散 注意是没有返回值的。打散原来的列表
l = [i for i in range(4)]
random.shuffle(l)
print(l) # [1, 3, 0, 2] 随机的改变
# choice方法返回一个列表,元组或字符串的随机项。
choice = random.choice([1, 2, 'hello'])
print(choice)
print(random.choice(('choose', 'wow'))) # 元组中随机的内容 如choose
print(random.choice('GOOD')) # 字符串返回的随机内容过
# 随机选择多个返回,返回的个数为函数的第二个参数, 注意返回的是一个列表
t = random.sample([1, '23', [4, 5]], 2)
print(t) # 如[[4, 5], 1]
print(random.sample('beautiful', 2)) # 如['l', 'a']
time
import time
# 时间元年至今的秒数(python是秒) 1970 1 月1 日 00:00
print(time.time()) # 1588829328.6471539
# 默认是当前系统时间的时间戳
# 格式化时间 格林尼治时间
print(time.gmtime())
# 当地时间
print(time.localtime())
# 年月日 时分秒 tm_wday; /* 星期 – 取值区间为[0,6],其中0代表星期一,1代表星期二,以此类推 */
# time.struct_time(tm_year=2020, tm_mon=5, tm_mday=7, tm_hour=13, tm_min=37, tm_sec=18, tm_wday=3, tm_yday=128, tm_isdst=0)
# 结构化时间 ---> 时间戳
t = time.localtime()
s = time.mktime(t)
print(s) # 1588853852.0
# 格式化时间对象和字符串转化 2020-05-07 13:55:35
s1 = time.strftime('%Y-%m-%d %H:%M:%S')
print(s1)
# 格式化时间 转化为结构化时间 注意前后的格式呀要对应
s = time.strptime('2020-5-07 08:01:00', '%Y-%m-%d %H:%M:%S' )
print(s)
import datetime
# date
d = datetime.date(2010, 5, 7)
print(d) # 2010-05-07
print(d.year) # 2010
# time
d = datetime.time(12, 59, 45)
print(d) # 12:59:45
print(d.hour) # 12
# datetime
print(datetime.datetime(2020, 5,7, 12, 11, 14)) # 2020-05-07 12:11:14
# datetime中的类, 主要用于数学计算 改变时候, 会有进位改变。 类型和操作的
# date, datetime, timedelta 之间能运算, 不能和time进行运算
t = datetime.datetime(2020, 5, 7, 12, 12, 59)
d =datetime.timedelta(seconds=3)
print(t+d) # 2020-05-07 12:13:02
# 3 月1 日前一天是29天 就是瑞年
t = datetime.date(2020, 3, 1)
d = datetime.timedelta(days=1)
res = t-d
print((t-d).day) # 29
# timedelta和另外一个数据相加(datetime, date), 结果类型是被加数的类型
# 以下返回的是date类型,所以秒数不会展示出来
d = datetime.timedelta(seconds=1)
d1 = datetime.timedelta(days=1)
t = datetime.date(2020, 5, 7)
print(t + d + d1) # 2020-05-08
json
import json
"""
序列化:
把内存中的数据,转换成字节或字符串的形式,以便于进行存储或者
网络传输.
内存中数据 -> 字节串/字符串 : 序列化
字节串/字符串 -> 内存中的数据 : 反序列化
"""
# 集合是不能够序列化的
# 序列化后的内容都是字符串类型
dic = {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
str_dic = json.dumps(dic) # 序列化:将一个字典转换成一个字符串
print(type(str_dic), str_dic) # <class 'str'> {"k3": "v3", "k1": "v1", "k2": "v2"}
# 注意,json转换完的字符串类型的字典中的字符串是由""表示的
dic2 = json.loads(str_dic) # 反序列化:将一个字符串格式的字典转换成一个字典
# 注意,要用json的loads功能处理的字符串类型的字典中的字符串必须由""表示
print(type(dic2), dic2) # <class 'dict'> {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
# 元组序列话之后,再反序列化,变成了列表
res = json.dumps((1, 2, 'hello'))
print(res, type(res)) # [1, 2, "hello"] <class 'str'>
l = json.loads(res)
print(l, type(l)) # [1, 2, 'hello'] <class 'list'>
# #dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件
# with open('2.txt', encoding='utf-8', mode='a') as f:
# # json.dump({'name': 'zhangsan', 'age': '16'}, f) # json.dump无返回值
# # print(res)
# load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回 。 load在反序列化字典时,字典也应该是双引号
# load 方式是一次性load出来的
# with open('2.txt', encoding='utf-8', mode='r') as f:
# res = json.load(f)
# print(res)
# 对于json序列化,存储多个数据到一个文件中是有问题的,默认一个json文件只能存储一个json数据,但是也可以解决,
# 写入文件
with open('2.txt', encoding='utf-8', mode='a') as f:
content = json.dumps({'name': 'zhagnsan', 'age':'16'})
f.write(content + '\n')
content = json.dumps(('wow', 666))
f.write(content + '\n')
with open('2.txt', encoding='utf-8', mode= 'r') as f:
for line in f:
print(json.loads(line.strip()))
pickle
# 序列化: 将python中所有的数据类型,转化为字节
# 反序列化, 将字节转化为python重的数据类型
import pickle
bys = pickle.dumps('中国')
print(bys) # b'\x80\x03X\x06\x00\x00\x00\xe4\xb8\xad\xe5\x9b\xbdq\x00.'
# pickle 反序列化元组时, 数据类型还是元组。 而json序列化/反序列化元组得到的是列表
bys = pickle.dumps((1, 2, 4))
print(bys)
print(pickle.loads(bys)) # (1, 2, 4)
# pickle支持集合序列化。 json不支持
bys = pickle.dumps({1, 'zhang'})
print(pickle.loads(bys)) # {1, 'zhang'}
# json:
# 1.不是所有的数据类型都可以序列化.结果是字符串.(集合不可以序列化, 元组序列化反序列化之后变成了列表)
# 2.不能多次对同一个文件序列化.(可以通过多次loads, 多次write, 在循环loads的方式实现)
# 3.json数据可以跨语言
#
# pickle:
# 1.所有python类型都能序列化,结果是字节串.
# 2.可以多次对同一个文件序列化
# 3.不能跨语言.
with open('3.txt', mode='ab') as f:
res = pickle.dump('hello', f)
print(res)
with open('3.txt', mode='rb') as f:
res = pickle.load(f)
print(res)
os sys
import os
# 删除文件
# os.remove('aa')
# 更改文件名
# os.rename('1.txt', '2.txt')
# 删除目录 (目录需要是空的)
# os.removedirs('目录')
# 路径相关的操作os.path
# 返回path的目录, 文件不存在不会报错
res = os.path.dirname(r'/PycharmProjects/learn_python/模块/2.txt')
print(res) # /PycharmProjects/learn_python/模块
# 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值,即os.path.split(path)的第二个元素。
res = os.path.basename(r'/PycharmProjects/learn_python/模块/2.txt')
print(res) # 2.txt
# 将path分割成目录和文件名二元组返回
res = os.path.split(r'/PycharmProjects/learn_python/模块/2.txt')
print(res) # ('/PycharmProjects/learn_python/模块', '2.txt')
res = os.path.join('home', 'hello', '1.txt')
print(res) # home/hello/1.txt
# 如果在不同位置添加/ 结果是不同的
print(os.path.join('home', '/hello', '1.txt')) # /hello/1.txt # 只有一个/ 以第一个的位置记录,前面的舍弃
print(os.path.join('home', '/hello', '/1.txt')) # /1.txt 有多个/ 以最后一个/ 记录
# 获得当前绝对路径
print(os.path.abspath('.'))
# 判断当前是不是绝对路径
print(os.path.isabs('/zhang.txt')) # true
print(os.path.isabs('zhang.txt')) # False
# 判断是不是目录, 是为True( 会找到对应的路径真实比较, 不能通过命名比较)
print(os.path.isdir('/not_exists.txt')) # 不存在返回false
# 判断是不是文件 如果文件不存在是false, 不能通过名字判断是文件还是目录,找到对应的路径真实比较
print(os.path.isfile('exists.txt'))
# 判断是否存在文件
print(os.path.exists(r'/PycharmProjects/learn_python/模块/2.txt'))
# 获取命令行方式运行的脚本后面的参数
# 不用IDE工具,只用命令行窗口运行的时候,进入文件所在目录,输入:python a.py 输出结果['a.py']
# 输入python a.py zhang 输出 ['a.py', 'zhang']
import sys
print(sys.argv)
md5
算出一个字符串的MD5值:
import hashlib
md5 = hashlib.md5()
md5.update('how to use md5 in python hashlib?')
print md5.hexdigest() # d26a53750bc40b38b65a520292f69306
如果数据量很大,可以分块多次调用update(),最后计算的结果是一样的:
md5 = hashlib.md5()
md5.update('how to use md5 in ')
md5.update('python hashlib?')
print md5.hexdigest()
摘要算法在很多地方都有广泛的应用。要注意摘要算法不是加密算法,不能用于加密(因为无法通过摘要反推明文),只能用于防篡改,但是它的单向计算特性决定了可以在不存储明文口令的情况下验证用户口令。
由于常用口令的MD5值很容易被计算出来,所以,要确保存储的用户口令不是那些已经被计算出来的常用口令的MD5,这一方法通过对原始口令加一个复杂字符串来实现,俗称“加盐”:
hashlib.md5("username".encode("utf8"))
Collection
from collections import namedtuple, defaultdict, Counter
# (1, 2),很难看出这个tuple是用来表示一个坐标的。
# 这时,namedtuple就派上了用场:
Point = namedtuple('Point', ['x', 'y'])
p = Point(1, 2)
print(p.x, p.y) # 1 2
my_dict = defaultdict(list)
print(my_dict)
# Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。
# 计数值可以是任意的Interger(包括0和负数)
c = Counter('abcdabccdd')
print(c) # Counter({'c': 3, 'd': 3, 'a': 2, 'b': 2})
print(c.most_common(3)) # [('c', 3), ('d', 3), ('a', 2)]
# ,如果引用的Key不存在,就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict:
from collections import defaultdict
d = defaultdict(int, name='Andy', age=10)
print(d['name']) # Andy
print(d['age']) # 10
print(d['addr']) # 0
print(d) # 不存在的值也被加入到字典了defaultdict(<class 'int'>, {'name': 'Andy', 'age': 10, 'addr': 0})
dic1 = defaultdict(lambda: 'N/A', {'name': 'zhang', 'age': '16'})
print(dic1['name']) # zhang
print(dic1['hobby']) # N/A
print(dic1) # defaultdict(<function <lambda> at 0x10a23e488>, {'name': 'zhang', 'age': '16', 'hobby': 'N/A'})
# 有如下值集合 [11,22,33,44,55,66,77,88,99,90...],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中。
# 即: {'k1': 大于66 , 'k2': 小于66}
li = [11, 22, 33, 44, 55, 77, 88, 99, 90]
result = {}
for i in li:
if i < 66:
if 'k1' not in result:
result['k1'] = []
result['k1'].append(i)
else:
if 'k2' not in result:
result['k2'] = []
result['k2'].append(i)
print(result) # {'k1': [11, 22, 33, 44, 55], 'k2': [77, 88, 99, 90]}
k = ['k1', 'k2']
li = [11, 22, 33, 44, 55, 77, 88, 99, 90]
from collections import defaultdict
content = [11, 22, 33, 44, 55, 77, 88, 99, 90]
my_dict = defaultdict(list)
for i in content:
if i < 66:
my_dict['k1'].append(i)
else:
my_dict['k2'].append(i)
print(my_dict) # defaultdict(<class 'list'>, {'k1': [11, 22, 33, 44, 55], 'k2': [77, 88, 99, 90]})