乐趣区

关于python:眼前一亮Python-高手都是这样处理数据的

工欲善其事,必先利其器!咱们想要更轻松更有效率地开发,必须学会一些“高级”技能。前不久看到一位 Python 高僧的代码,其中应用了一个短小精悍的模块,我认为还蛮有用的,明天分享给大家。

这个模块就叫 glom,是 Python 解决数据的一个小模块,它具备如下特点:

  • 嵌套构造并基于门路拜访
  • 应用轻量级的 Pythonic 标准进行申明性数据转换
  • 可读、有意义的错误信息
  • 内置数据探测和调试性能

看起来比拟形象,对不对?上面咱们用实例来给大家演示一下。

装置
作为 Python 内置模块,置信你肯定晓得怎么装置:

pip3 install glom

几秒钟就搞定!

简略应用
咱们来看看最简略的用法:

d = {"a": {"b": {"c": 1}}}
print(glom(d, "a.b.c")) # 1

在这里,咱们有一个嵌套三层的 json 构造,咱们想获取最里层的 c 对应的值,失常的写法应该是:

print(d["a"]["b"]["c"])

如果到这里,我说 glom 比传统形式好一些,因为你不必一层层地写中括号和引号,你会不会不屑一顾?

好,咱们再来看看上面的状况:

d = {"a": {"b": None}}
print(d["a"]["b"]["c"])

遍历到一个 None 对象,你会收到上面的谬误:

Traceback (most recent call last):
  File "/Users/cxhuan/Documents/python_workspace/mypy/pmodules/pglom/glomstudy.py", line 10, in <module>
    print(d["a"]["b"]["c"])
TypeError: 'NoneType' object is not subscriptable

咱们来看看 glom 的解决形式:

from glom import glom

d = {"a": {"b": None}}
print(glom(d, "a.b.c"))

同样地,glom 不能把谬误的输入成对的,你会失去以下谬误:

Traceback (most recent call last):
  File "/Users/cxhuan/Documents/python_workspace/mypy/pmodules/pglom/glomstudy.py", line 11, in <module>
    print(glom(d, "a.b.c"))
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/glom/core.py", line 2181, in glom
    raise err
glom.core.PathAccessError: error raised while processing, details below.
 Target-spec trace (most recent last):
 - Target: {'a': {'b': None}}
 - Spec: 'a.b.c'
glom.core.PathAccessError: could not access 'c', part 2 of Path('a', 'b', 'c'), got error: AttributeError("'NoneType' object has no attribute 'c'")

如果你认真看报错内容,你就会发现这报错内容极其具体,高深莫测,这对于找程序 bug 几乎是神器!

简单用法
方才简略的例子,让大家对 glom 有了直观的意识,接下来咱们看看 glom 的 glom 办法的定义:

glom(target, spec, **kwargs)

咱们看看参数的含意:

  • target:指标数据,能够是 dict、list 或者其余任何对象
  • spec:是咱们心愿输入的内容
    上面咱们来应用这个办法。

先看一个例子。咱们有一个 dict,想要获取出 所有 name 的值,咱们能够通过 glom 来实现:

data = {"student": {"info": [{"name": "张三"}, {"name": "李四"}]}}
info = glom(data, ("student.info", ["name"]))
print(info) # ['张三', '李四']

如果用传统形式的话,咱们可能会须要遍历能力获取到,然而应用 glom,咱们只须要一行代码就能够了,输入是一个数组。

如果你不想输入数组,而是想要一个 dict 的话,那也是很简略的:

info = glom(data, {"info": ("student.info", ["name"])})
print(info) # {'info': ['张三', '李四']

咱们只须要将原来的数组赋值给一个字典来接管就好了。

搞定麻烦需要
如果我当初有两组数据,我要取出 name 的值:

data_1 = {"school": {"student": [{"name": "张三"}, {"name": "李四"}]}}
data_2 = {"school": {"teacher": [{"name": "王老师"}, {"name": "赵老师"}]}}

spec_1 = {"name": ("school.student", ["name"])}
spec_2 = {"name": ("school.teacher", ["name"])}
print(glom(data_1, spec_1)) # {'name': ['张三', '李四']}
print(glom(data_2, spec_2)) # {'name': ['王老师', '赵老师']}

咱们通常是这么写,对吗?如果咱们有好多组数据,每组都是相似的取法呢?这时候咱们就会想方法防止一个个反复写 N 行参数了,咱们能够应用 Coalesce 办法:

data_1 = {"school": {"student": [{"name": "张三"}, {"name": "李四"}]}}
data_2 = {"school": {"teacher": [{"name": "王老师"}, {"name": "赵老师"}]}}

spec = {"name": (Coalesce("school.student", "school.teacher"), ["name"])}
 
print(glom(data_1, spec)) # {'name': ['张三', '李四']}
print(glom(data_2, spec)) # {'name': ['王老师', '赵老师']}

咱们能够用 Coalesce 把多个需要聚合起来,而后针对同一个 spec 来取值就行了。

上面再来一个大杀器——取值计算。glom 还能够对取值进行简略计算,咱们来看例子:

data = {"school": {"student": [{"name": "张三", "age": 8}, {"name": "李四", "age": 10}]}}
spec = {"sum_age": ("school.student", ["age"], sum)}
print(glom(data, spec)) # {'sum_age': 18}

总结
介绍了这么多,大家应该晓得 glom 的厉害之处了吧,据说很多大佬都喜爱应用呢。其实它还有很多其余的实用功能有待大家去挖掘,这里就不一一介绍了。

以上就是本次分享的所有内容,想要理解更多 python 常识欢送返回公众号:Python 编程学习圈,每日干货分享

退出移动版