最近碰到一个情况,一个python字典,得先转为字符串,再转回字典,最后切片去掉前面3个;
此时有两个问题:
①字典构造的时候,用的都是单引号,在使用JSON将字符串转回python字典的时候,会报错;
②转回字典的时候,如何优雅地切片;
1.字典与字符串相互转换问题
- # 先构造一个字典
- dict_1 = {'a':1,'b':2,'c':3,'d':4,'e':5,'f':6,'g':7,'h':8,'i':9,'j':10}
- print(dict_1,type(dict_1)) # <class 'dict'>
- # 将字典转为字符串
- dict_1_str = str(dict_1)
- print(dict_1_str,type(dict_1_str)) <class 'str'>
复制代码 此时dict_1_str是字符串类型,如果想转回字典- # 用json.loads(dict_1_str),会报错
- import json
- dict_1_back = json.loads(dict_1_str) # 尝试转回字典
- print(dict_1_back,type(dict_1_back))
- # 报错内容
- json.decoder.JSONDecodeError:
- Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
- #原因是JSON要求是 " 双引号,而我们用的单引号,总不能replace一遍吧;
- #虽然可以,但不聪明,如果字典嵌套比较多,容易出各种意外
- # 解决办法
- import ast # 这个库可以解析单引号
- str_to_dict = ast.literal_eval(dict_1_str)
- print(str_to_dict,type(str_to_dict)) # <class 'dict'>
- # 那么相互转化的问题已经解决
复制代码 2.字典切片
还是用回最开始瞎编的字典dict_1 = {'a':1,'b':2,'c':3,'d':4,'e':5,'f':6,'g':7,'h':8,'i':9,'j':10}
现在比较新的python版本,3.7以后,字典顺序其实是固定了,但本质上是无序的,使用上保持了插入的顺序;
假如我想去掉前面3个,只留后面的,有以下几个方法,不过很多方法要生成中间列表,这样耗时耗内存;- # 方法1,先转列表再切片,再转回字典-->不推荐,数据大耗内存
- # 有很多写法,核心是先转列表,再筛选,再转回字典
- sliced_dict = dict(list(dict_1.items())[3:])
- print(sliced_dict) # 输出{'d': 4, 'e': 5, ...'i': 9, 'j': 10}
- # 方法2,字典推导式,根据条件筛选--->键值对简单的情况下适用,还不错
- filtered_dict = {k: v for k, v in dict_1.items() if 3 < v <= 10}
- print(filtered_dict) # 条件可以是key,也可以是value
- # 也可以用下面的写法,实际差不多
- filtered_dict = {k: dict_1[k] for k in dict_1.keys() if k.startswith('a')}
复制代码
这样会报错哦- # 方法3,itertools.islice(迭代器切片)-->最佳内存方案
- from itertools import islice
- def get_need_items(dct, n):
- """高效获取字典前N个键值对"""
- return dict(islice(dct.items(), n))
- # 查看源码,发现可以给的参数,就跟普通切片差不多
- # 如果只给1个int参数,就是取前多少个
- # 注意参数必须为0到max(length),传负数,像列表一样反着切是不行的
- # 但稍微变一下,一样可以为所欲为
- class islice(object):
- """
- islice(iterable, stop) --> islice object
- islice(iterable, start, stop[, step]) --> islice object
-
- Return an iterator whose next() method returns selected values from an
- iterable. If start is specified, will skip all preceding elements;
- otherwise, start defaults to zero. Step defaults to one. If
- specified as another value, step determines how many values are
- skipped between successive calls. Works like a slice() on a list
- but returns an iterator.
- """
- # 那么我们修改一下方法
- from itertools import islice
- def get_need_items(dct, *args):
- return dict(islice(dct.items(), *args))
- 前五个=get_need_items(dict_1, 0, 5)
- 除开前三个 = get_need_items(dict_1, 3, None)
- 从第三到倒数第三个 = get_need_items(dict_1, 2, len(dict_1)-2)
- print(前五个)
- print(除开前三个)
- print(从第三到倒数第三个)
复制代码
参考:
Python如何将字符串(str/json)转换字典(dict)-1
参考-2
Python字典技巧:3种高效提取前N个键值对的方法,你选哪种?-3
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |