python常见的容器类型有: 列表,元组,字典,集合
列表list:存放多个不同类型的对象
元组tuple:初始化之后就不可修改的list
字典dict: key-value类型的数据
集合set:不可重复列表的
1、遍历的时候获取下标
循环遍历的时候,会逐个拿到成员,但是有时候想同时获得下标,可以选择内置的函数
enumerate() 实现, enumerate() 适用于任何 可迭代对象,列表,元组,字符串等。
names = ['jerry', 'tome']
for index, value in enumerate(names):
print(index, value)
2、列表推导式
处理某个列表的需求:1、修改某些值 2、剔除某些值 ,然后产生一个新的列表。
可以采用列表推导式:写法比较简单,类似filter,然后做处理
>>> numbers = [1,2,3,4,5]
>>> result = [n * 100 for n in numbers if n % 2 == 0]
>>> result
[200, 400]
3、列表可变性
python内置类型分为可变和不可变:
可变:列表,字典,集合
不可变:整数 浮点数 字符串 字节串 元组
3.1 字符串添加内容
orgin_str = "abc"
def add_str(in_str):
print(f"receive: {in_str}")
in_str += " add"
print(f"add after: {in_str}")
print(orgin_str)
add_str(orgin_str)
print(orgin_str)
#输出
abc
receive: abc
add after: abc add
abc
通过输出可以看到传入的字符串在方法内添加了字符串,但是方法外的原来的字符串并没有被修改
3.2 为列表添加内容
orgin_list = ['abc','def']
def add_list(in_list):
print(f"receive : {in_list}")
in_list.append(' add')
print(f"list add after : {in_list}")
print(orgin_list)
add_list(orgin_list)
print(orgin_list)
#输出
['abc', 'def']
receive : ['abc', 'def']
list add after : ['abc', 'def', ' add']
['abc', 'def', ' add']
通过输出可以看到,在方法内为列表添加的修改,原始变量也发生了变化。
3.3 解释
Python方法传参: 传递的是变量所指向的引用。函数内的变量和外部的变量指向同一个对象,对方法内部的变量进行修改时,是否影响外部变量,主要取决于指向的对象是否是可变对象。
可变对象: 修改该变量,因为指向同一个对象,所以函数外部的原始变量也会被修改,列表添加的列子。
不可变对象: 修改该变量,重新产生一个新的对象,并让内部的变量指向新的对象,原始变量指向原来的对象,所以修改对原来的对象没有产生影响。 字符串添加的例子
4、Python方法返回多个结果
python方法会返回多个值,这个其他语言就不一定支持,例如java,go等语言,方法只返回一个;
python方法没有明确指定返回值,返回多个结果的方法,就是把多个结果组装成一个元组返回;
def get_result():
width = 100
height = 200
return width,height
print(type(get_result()))
# 输出
<class 'tuple'>
元组适合存放结构化的数据,可以存放一个对象的多个属性;
默认的元组只能通过索引获取值,不太方便,python提供一个: 有名字的元组,类似于key-value,可以通过名称访问成员
from collections import namedtuple
result = namedtuple('Result', 'width,height')
result_rsp = result(width=100, height=200)
print(result_rsp.width)
print(result_rsp.height)
5、字典中不存在的key
5.1 访问不存在的key
dict[key] 如果key不存在会抛出KeyError异常,有异常会导致方法执行结束,所以通过这种方式获取字典的值需要处理异常。
一般有三种方式:
1、提前判断key是否存在,再访问。
person = {"name": "jerry", "age": 18, "address": "wuhan"}
# print(person['money'])
if 'money' in person:
result = person['money']
print(result)
else:
result = 0
print(result)
2 、try... except 处理这异常。这种方式优于第一种。
person = {"name": "jerry", "age": 18, "address": "wuhan"}
try:
result = person['money']
print(result)
except KeyError:
result = 0
print(result)
3、如果只是为了获取值,如果key不存在返回默认值,这种方式更加简单dict.get(key,default)
person = {"name": "jerry", "age": 18, "address": "wuhan"}
# 如果不存在就,返回默认值0
person.get('money', 0)
5.2 修改不存在的key
1、如果key不存在,就会抛出异常,捕获异常处理
person = {"name": "jerry", "age": 18, "address": "wuhan"}
## 修改
try:
person['money'].append('value')
except KeyError:
person['money'] = ['value']
print(person)
2、dict.setdefault(key,default=None) 方式,可以省去异常捕获。
当key不存在时,就会把key放入该dict,并且设置值为默认值,并返回该值。
当key存在时,就会直接返回dict中key对应的值。
person = {"name": "jerry", "age": 18, "address": "wuhan"}
person.setdefault('money', []).append('value')
print(person)
person.setdefault('money', []).append('hello')
print(person)
#输出
{'name': 'jerry', 'age': 18, 'address': 'wuhan', 'money': ['value']}
{'name': 'jerry', 'age': 18, 'address': 'wuhan', 'money': ['value', 'hello']}
5.3 删除不存在的key
删除dict中的key一般可以采用 del dict[key], 如果要删除的key不存在会抛出KeyError异常
person = {"name": "jerry", "age": 18, "address": "wuhan"}
try:
del person['money']
except KeyError:
# 忽略key不存在的
pass
dict.pop(key,default) 删除字典给定键 key 所对应的值,返回值为被删除的值。
- 如果
key
存在 - 删除字典中对应的元素 - 如果
key
不存在 - 返回设置指定的默认值 default - 如果
key
不存在且默认值 default 没有指定 - 触发KeyError
异常
person = {"name": "jerry", "age": 18, "address": "wuhan"}
print(person.pop('name', None))
print(person.pop('money', None))
print(person)
#输出
jerry
None
{'age': 18, 'address': 'wuhan'}
6 字典推导式
对字典通过key进行过滤,并且对值进行处理,生成新的字典
person = {"name": "jerry", "age": 18, "address": "wuhan"}
person2 = {key: value + 10 for key, value in person.items() if key == 'age'}
print(person2)
#输出
{'age': 28}
7 字典的有序性
Python3.6 以前,开发者默认 : python的字典是无序的,无序是指按照顺序放进去,无法按照顺序取出来。但是python3.6 优化了底层实现,python3.7 已经默认 python字典是有序的,取出来的顺序和放进去的顺序是一致。
字典的底层key的存储是哈希表存储的,就是key必须是一个可以哈希的对象。
d = {}
for x in range(10):
d[str(x)] = x
print(d)
for x in d:
print(x)
#输出 python 2.7 .18
{'1': 1, '0': 0, '3': 3, '2': 2, '5': 5, '4': 4, '7': 7, '6': 6, '9': 9, '8': 8}
1
0
3
2
5
4
7
6
9
8
#输出 python3.9 多次执行结果都是顺序的
{'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
0
1
2
3
4
5
6
7
8
9
8 集合set可以存放那些对象?
集合set中只能存放可哈希的对象,就是调用内置函数hash(obj),返回一个整型结果的对象,如果不能被哈希则抛出异常KeyError: unhashable ;
是否可哈希总结:
1、所有不可变的内置型,都是可以哈希的, str 、int、tuple(有条件)、frozenset 等
2、所有可变的内置类型,都是不可哈希的,list,dict,set 等
3、对于不可变的类型,tuple和frozenset , 仅当所有成员都是不可变时,才是可以哈希的对象
4、用户自定义的class的实例对象都是可以哈希的。
set_test = set()
set_test.add('123')
set_test.add('name')
tuple_one = (1,2,3)
set_test.add(tuple_one)
print(set_test)
tuple_two = (1,2,['12','23'])
set_test.add(tuple_two)
#输出
{'name', (1, 2, 3), '123'}
TypeError: unhashable type: 'list'
tuple_one 可以添加成功,tuple_two 添加失败。
9 深拷贝与浅拷贝
python中对象拷贝,如果在操作一个可变对象时,不希望影响原始数据,先拷贝再修改,不拷贝原始对象就修改,可能会对原始数据产生影响。
浅拷贝
通过copy模块下的copy方法实现浅拷贝
import copy
nums = [1,2,3,4]
nums_copy = copy.copy(nums)
nums[2] = 20
nums_copy[1] = 10
print(nums)
print(nums_copy)
# 输出
[1, 2, 20, 4]
[1, 10, 3, 4]
浅拷贝的其他几种实现
1、通过list和dict 这种构造函数,能够实现浅拷贝
2、通过切片实现浅拷贝。
3、list和dict自带的copy方法
nums = [1,2,3,4]
nums_list_copy = list(nums)
d = {'name':'jerry', 'age':18}
dict_copy = dict(d.items())
nums_copy_2 = nums[:]
nums_copy_3 = nums.copy()
d_copy = d.copy()
浅拷贝的问题:有嵌套层级的时候
import copy
nums = [1, 2, 3, ["name", "age"]]
nums_copy = copy.copy(nums)
nums_list_copy = list(nums)
nums_copy_2 = nums[:]
nums_copy_3 = nums.copy()
nums[3].append("address")
print(nums)
print(nums_copy)
print(nums_list_copy)
print(nums_copy_2)
print(nums_copy_3)
#输出
[1, 2, 3, ['name', 'age', 'address']]
[1, 2, 3, ['name', 'age', 'address']]
[1, 2, 3, ['name', 'age', 'address']]
[1, 2, 3, ['name', 'age', 'address']]
[1, 2, 3, ['name', 'age', 'address']]
通过输出可以看到,修改原始数据,copy的新数据也发生了改变, 本质是copy的list中嵌套的list只是copy了地址,两个对象中嵌套的list指向同一个list,修改会彼此影响。
print(id(nums),id(nums_copy))
print(id(nums[3]), id(nums_copy[3]))
# 输出
4552674880 4554515648
4554395136 4554395136
深拷贝
深拷贝就是为了解决上面的嵌套问题,彻底copy对象,新旧对象修改不被互相影响。
使用copy.deepcopy()函数实现:
import copy
nums = [1, 2, 3, ["name", "age"]]
nums_copy = copy.deepcopy(nums)
nums[3].append("address")
print(nums)
print(nums_copy)
print(id(nums),id(nums_copy))
print(id(nums[3]), id(nums_copy[3]))
# 输出
[1, 2, 3, ['name', 'age', 'address']]
[1, 2, 3, ['name', 'age']]
4470107712 4471952704
4471832128 4471955200
10 生成器generator
生成器(generator)是python里特殊的数据类型,可以不断返回给调用方的生成内容的类型。
按需生成,类似其他语言的懒加载,先返回结果生成器,再调用next() 时候才会再去生成结果并返回。这是python的一种编程思想-按需返回,而不是一次返回所有列表。
print(type(range(10)))
#输出
<class 'range'>
range(num) 返回的数列就是一个生成器,并不是返回了一个列表,只是在迭代的时候才会不断生成新的数字;
定义生成器:
def generator_num(max_num):
"""返回0-max之间的偶数"""
for x in range(max_num):
print(f"被调用了一次-{x}")
if x % 2 == 0:
yield x
print(type(generator_num(10)))
for i in generator_num(10):
print(i)
#输出
<class 'generator'>
被调用了一次-0
0
被调用了一次-1
被调用了一次-2
2
被调用了一次-3
被调用了一次-4
4
被调用了一次-5
被调用了一次-6
6
被调用了一次-7
被调用了一次-8
8
被调用了一次-9
通过循环迭代生成器,可以看到,只有在被迭代的时候,生成器内部才开始调用。
next(generator) 可以获得迭代器里面的内容。
list(generator) 可以直接将生成器的结果转化为list对象。
用生成器替代列表
如果函数的处理是:初始化容器-->循环处理元素-->将结果存入新的容器---> 返回容器
一般这种处理过程会这样写:
def process_items(items):
result = []
for item in items:
# do something 可能处理时间比较长,可能这个items量非常的大
result_item = 'xxx'
result.append(result_item)
return result
1、问题1 : 可能这个items量非常的大,可能 单个元素处理时间比较长,返回的result比较大,也会比较占用内存。
2、问题2: 返回的 result_item 满足特定条件中断执行。目前函数里面也是无法做到。
解决这两个问题,就是需要改写为生成器
def process_items(items):
for item in items:
# do something 可能处理时间比较长,可能这个items量非常的大
result_item = 'xxx'
yield result_item
# 调用
list = list(range(10))
for result_item in process_items(items=list):
# 如果满足条件,就会终止执行,也会结束生成器的执行
if result_item.has_expired():
break
# todo something
11 容器的底层实现
list的两种插入数据比较:
def list_append():
l = []
for x in range(5000):
l.append(x)
def list_insert():
l = []
for x in range(5000):
l.insert(0,x)
append_time = timeit.timeit(setup='from __main__ import list_append', stmt='list_append()', number=10000)
print("append_time :", append_time)
insert_time = timeit.timeit(setup='from __main__ import list_insert', stmt='list_insert()', number=10000)
print("insert_time :", insert_time)
# 输出
append_time : 2.770407401
insert_time : 67.36323991100001
两种添加列表的方式不同,生成一个长度为5000的列表,耗时相差30倍。这种原因是list的底层实现时数组,数组追加操作的平均时间复杂度是O(1), 如果数组从头部插入成员,其他成员都要移动位置, 所以平均时间复杂度是O(n);
python有没有数组类型? 其实python没有数组类型,其他语言基本都有数组这个类型。python提供的list比数组的功能要更加强大,一般语言的数组是存放多个同类对象数据,python的list可以存放多种不同功类型的对象数据;
如果需要经常在列表头部插入数据,可以采用collections 提供的 deque ,底层实现了双端队列,头部和尾部添加成员复杂度都是O(1)。
from collections import deque
def deque_append():
l = deque()
for x in range(5000):
l.append(x)
def deque_appendleft():
l = deque()
for x in range(5000):
l.appendleft(x)
append_time = timeit.timeit(setup='from __main__ import deque_append', stmt='deque_append()', number=10000)
print("append_time :", append_time)
insert_time = timeit.timeit(setup='from __main__ import deque_appendleft', stmt='deque_appendleft()', number=10000)
print("insert_time :", insert_time)
# 输出
append_time : 2.772019173
insert_time : 2.7395239540000005
列表的查找问题:如果列表特别大,查找某个成员是否存在,需要从前往后逐个对比,如果是最后一个,平均时间复杂度就是O(n) 。 如果判断成员是否存在,有些地方会你可能会看到,可以将列表转换为集合,再通过集合查找可以提高效率。集合是哈希表数据结构,查找快,好像没有什么问题,但是实际测试, 把一个大的列表转换为集合,存储也是需要一定时间的。这么做实际上会降低效率,不信自己测试去看看吧。
import time
l = []
for x in range(50000001):
l.append(x)
start = time.time()
print(50000000 in l, time.time() -start)
start = time.time()
s = set(l)
print(time.time() - start)
start = time.time()
print(50000000 in s,time.time() - start )
# 输出
True 0.581557035446167
4.345677137374878
True 2.1457672119140625e-06
12 两个字典的合并
两个字典的合并
1、 d1.update(d2) , 这种方式合并字典d1会被修改,有副作用的合并。
d_1 = {'name': 'jerry', 'age': 18}
d_2 = {'name': 'tom', 'adress': 'wuhan'}
d_1.update(d_2)
print(d_1)
2、利用动态解包的特点 **dict 解包合并,可以生成新的字典,对原理的数据无副作用,注意解包:默认进行了浅拷贝。
d_1 = {'name': 'jerry', 'age': 18}
d_2 = {'name': 'tom', 'adress': 'wuhan'}
d_new = {**d_1, **d_2}
print(d_new)
print(d_1)
# 输出
{'name': 'tom', 'age': 18, 'adress': 'wuhan'}
{'name': 'jerry', 'age': 18}
3、python 3.9 的 合并运算
注意;运算顺序不同结果会有差异,同样的key,右边的会把左边的修改
d_1 = {'name': 'jerry', 'age': 18}
d_2 = {'name': 'tom', 'adress': 'wuhan'}
print(d_1 | d_2)
print(d_2 | d_1)
# 输出
{'name': 'tom', 'age': 18, 'adress': 'wuhan'}
{'name': 'jerry', 'adress': 'wuhan', 'age': 18}
使用*obj可以解包任何可迭代对象, 使用**dict解开dict包,这两种方式在python传入参数的时候很常见。
13 列表去重复且保持原有顺序
一般的set可以去重但是无法保持原来顺序,如果要保持原来的顺序需要使用OrderDict来完成这件事。
from collections import OrderedDict
num = [2, 3, 10, 20,'123', 5, 2, 30, 3, ]
print(num)
# 虽然去重了,但是原来的顺序乱了,如果是数字的话,好像还默认给排序了。
s = list(set(num))
print(s)
# 保持原有顺序,且去重
num_new = list(OrderedDict.fromkeys(num).keys())
print(num_new)
## 输出
[2, 3, 10, 20, '123', 5, 2, 30, 3]
[2, 3, 5, 10, '123', 20, 30]
[2, 3, 10, 20, '123', 5, 30]
14 代码优化
需求:处理http的请求日志,分析不同url的性能占比, 要求如下:
原始数据:
/v1/login/ 200
/v2/admin/ 260
/v1/queryData/ 400
...
输出结果:
Path: /v1/login/
Total request: 800
Performance:
- Less than 100ms : 100
- Between 100 and 300ms : 200
- Between 300 and 1s : 200
- More than 1s : 300
Path: ...
测试数据:
/v1/login/ 200
/v2/admin/ 300
/v1/queryData/ 400
/v1/login/ 100
/v2/admin/ 89
/v1/queryData/ 400
/v1/login/ 98
/v2/admin/ 80
/v1/queryData/ 400
/v1/login/ 200
/v2/admin/ 260
/v1/queryData/ 400
/v1/login/ 1000
/v2/admin/ 800
/v1/queryData/ 1080
/v1/login/ 200
/v2/admin/ 260
/v1/queryData/ 400
/v1/login/ 200
/v2/admin/ 1050
/v1/queryData/ 400
/v1/login/ 2000
/v2/admin/ 260
/v1/queryData/ 250
/v1/login/ 400
/v2/admin/ 800
/v1/queryData/ 900
第一个版本代码
def analyze_log():
path_dict = {}
with open("log.txt", "r") as file:
for line in file:
path, time_cost = line.strip().split()
rsp_time = int(time_cost)
if rsp_time < 100:
level = 'Less than 100ms'
elif rsp_time < 300:
level = 'Between 100 and 300ms'
elif rsp_time < 1000:
level = 'Between 300 and 1s'
else:
level = 'More than 1s'
# 不存在加入空
if path not in path_dict:
path_dict[path] = {}
# 计数
try:
path_dict[path][level] += 1
except KeyError:
path_dict[path][level] = 1
for path, result in path_dict.items():
print(f'===Path: {path}')
total = sum(result.values())
print(f'Total request: {total}')
print(f'Performance:')
for level_name, count in result.items():
print(f' - {level_name} : {count}')
if __name__ == '__main__':
analyze_log()
第一个版本代码可以基本满足需求:
#结果如下
===Path: /v1/login/
Total request: 9
Performance:
- Between 100 and 300ms : 5
- Less than 100ms : 1
- More than 1s : 2
- Between 300 and 1s : 1
===Path: /v2/admin/
Total request: 9
Performance:
- Between 300 and 1s : 3
- Less than 100ms : 2
- Between 100 and 300ms : 3
- More than 1s : 1
===Path: /v1/queryData/
Total request: 9
Performance:
- Between 300 and 1s : 7
- More than 1s : 1
- Between 100 and 300ms : 1
但是存在以下问题
1、级别level 这种类型的数据,最好用枚举替代,定义比较清楚,后续修改级别也只需修改一处。
2、所有功能都融合在一个方法里面,读取文件,处理逻辑和输出,这个最好分开去处理。
3、if path not in path_dict 和 try... expect的写法可以使用get() 和setdefault() 来优化。
4、 返回的统计结果没有按照顺序优化,这个可以通过枚举的定义的level来排序优化。
第二个优化版本:
from enum import Enum
class PerfLevel(str, Enum):
Level_100 = 'Less than 100ms'
Level_300 = 'Between 100 and 300ms'
Level_1000 = 'Between 300 and 1s'
Level_M_1000 = 'More than 1s'
def analyze_log():
path_dict = {}
with open("log.txt", "r") as file:
for line in file:
path, time_cost = line.strip().split()
rsp_time = int(time_cost)
if rsp_time < 100:
level = PerfLevel.Level_100
elif rsp_time < 300:
level = PerfLevel.Level_300
elif rsp_time < 1000:
level = PerfLevel.Level_1000
else:
level = PerfLevel.Level_M_1000
path_dict.setdefault(path, {})
num = path_dict[path].get(level, 0)
path_dict[path][level] = num + 1
for path, result in path_dict.items():
print(f'===Path: {path}')
total = sum(result.values())
print(f'Total request: {total}')
print(f'Performance:')
sorted_result = sorted(result.items(), key=lambda p: list(PerfLevel).index(p[0]))
for level_name, count in sorted_result:
print(f' - {level_name} : {count}')
if __name__ == '__main__':
analyze_log()
进一步优化代码:
1、通过 defaultdict(default_factory,...) 类型优化字典的的操作,defaultdict是一种特殊类型的字典,接受一个default_factory 函数作为参数,如果d[key]访问,key不存在,就是调用default_factory生成结果作为value,将key-value 存入字典。
from collections import defaultdict
d = defaultdict(int)
d['name'] += 1
print(d)
print(dict(d))
def get_default_value():
return 100
d_2 = defaultdict(get_default_value)
# key不存在就会调用默认值,而且存储到了dict中,并且返回了值
d_2['money'] += 1
d_2['name'] = 'jerry'
print(dict(d_2))
# 输出
defaultdict(<class 'int'>, {'name': 1})
{'name': 1}
{'money': 101, 'name': 'jerry'}
2、使用MultableMapping创建自定义的字典类型。继承MultableMapping的抽象类来实现。
from enum import Enum
from collections.abc import MutableMapping
from collections import defaultdict
class PerfLevel(str, Enum):
Level_100 = 'Less than 100ms'
Level_300 = 'Between 100 and 300ms'
Level_1000 = 'Between 300 and 1s'
Level_M_1000 = 'More than 1s'
class PerfLevelDict(MutableMapping):
def __init__(self):
self.data = defaultdict(int)
def __setitem__(self, key, value) -> None:
self.data[self.compute_level(key)] = value
def __delitem__(self, key) -> None:
del self.data[key]
def __getitem__(self, key):
return self.data[self.compute_level(key)]
def __len__(self):
return len(self.data)
def __iter__(self):
return iter(self.data)
@staticmethod
def compute_level(time_str):
if time_str in list(PerfLevel):
return time_str
rsp_time = int(time_str)
if rsp_time < 100:
return PerfLevel.Level_100
elif rsp_time < 300:
return PerfLevel.Level_300
elif rsp_time < 1000:
return PerfLevel.Level_1000
return PerfLevel.Level_M_1000
def analyze_log():
path_dict = defaultdict(PerfLevelDict)
with open("log.txt", "r") as file:
for line in file:
path, time_cost = line.strip().split()
path_dict[path][time_cost] +=1
for path, result in path_dict.items():
print(f'===Path: {path}')
total = sum(result.values())
print(f'Total request: {total}')
print(f'Performance:')
sorted_result = sorted(result.items(), key=lambda p: list(PerfLevel).index(p[0]))
for level_name, count in sorted_result:
print(f' - {level_name} : {count}')
if __name__ == '__main__':
analyze_log()
代码优化是更加结构化了,逻辑被封装进去自定义的字典里面了,但是代码的可读性和理解性下降了,装逼是可以的,实际好像很少这么玩的。
15 排序问题
列表有一个内置的list.sort()方法可以排序,会直接修改列表。还有一个 sorted() 内置函数,可以排序,它会从一个可迭代对象构建一个新的排序列表,不会修改原数据。
sort()方法和sorted()函数增加了key参数来指定一个函数,此函数将在每个元素比较前被调用。
key参数的值为一个函数,此函数只有一个参数且返回一个值用来进行比较。
一种常见的模式是使用对象的一些索引作为键对复杂对象进行排序。
student_tuples = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'D', 10), ('jerry', 'C', 5)]
sorted_student = sorted(student_tuples, key=lambda x: x[1])
print(sorted_student)
sorted_student_2 = sorted(student_tuples, key=lambda x: x[2])
print(sorted_student_2)
# 输出
[('john', 'A', 15), ('jane', 'B', 12), ('jerry', 'C', 5), ('dave', 'D', 10)]
[('jerry', 'C', 5), ('dave', 'D', 10), ('jane', 'B', 12), ('john', 'A', 15)]
字典通过key排序或者通过value排序。
# 对键排序
dict1={'a':2,'e':3,'f':8,'d':4}
list1= sorted(dict1.items(),key=lambda x:x[0])
print(list1)
# 对值排序
dict1={'a':2,'e':3,'f':8,'d':4}
list1= sorted(dict1.items(),key=lambda x:x[1])
print(list1)
字典组成的列表排序:
dic = [{"goods_id":3,"user_id":11, "score":0.8},
{"goods_id":1,"user_id":22, "score":0.1},
{"goods_id":2,"user_id":33, "score":0.5}]
sorted(dic, key=lambda x:x['score'], reverse=True)