这是作者(Loco)在PyCon China 2020 上海场闪电演讲内容的文字版本。

快速将两个分别存放有key和value的列表合并成一个字典

>>>a = ["key1", "key2", "key3"]>>>b = ["value1", "value2", "value3"]>>>dict(zip(a, b)){'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}

这个操作的用途对于爬虫工程师而言挺常见的,比如说:

你需要采集一些键值对类型的信息,然后你可能会碰到一些平台的接口返回这些信息时是直接返回的一个只有value的列表,并且key都是写死在代码或请求参数里的,这时候你就可以通过这个操作来将它们快速合并成一个字典,这样就能比较方便地取值了,取值部分的可读性也会好很多。

还有一种情况就是,你可能会碰到一些网站上的这种键值对信息在HTML中key和value的元素是平级关系,并且key和value也没有能够区分的标识,这些情况我们只能通过把整个键值对部分的元素都提取出来转换成列表,然后再通过按列表下标间隔切片的方式分别取出key和value的列表,然后再将它们合并成一个字典。比如这样:

>>> result = ["key1", "value1", "key2", "value2", "key3", "value3"]>>> result[0::2]['key1', 'key2', 'key3']>>> result[1::2]['value1', 'value2', 'value3']>>> dict(zip(result[0::2], result[1::2])){'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}

需要注意的是,这个操作在碰到key和value数量不一致的时候,会自动忽略掉多的那部分列表尾部的值,你需要确保key和value是对得上的才行。

简单来说就是,如果你的key列表比value列表多一个值,那么最终出来的字典就会缺失掉key列表中的最后那一个多出来的值。

快速按头、尾、中间部分切割元素,并将它们分别赋值给三个变量

>>> a = "123456789" # 也可以是list之类的>>> a1, *a2, a3 = a>>> a1'1'>>> a2['2', '3', '4', '5', '6', '7', '8']>>> a3'9'

这个操作的用途,对于爬虫工程师或者是一些会接触到私有协议的后端工程师应该都挺常见的,比如说:

你可能会碰到一些基于TCP或UDP搞的私有协议,然后它们可能会定义一个由内容类型头、通信内容、校验码之类的东西组成的结构,每次通信时都会给你返回这么一个东西,然后你需要将它们切开并赋值给不同的变量,这时候你就可以通过这个操作来快速实现这个效果了。

当然,这个操作也不能乱用,你最好是能够确保它的内容不会变化,像私有协议这种情况,你可以判断一下协议版本号之类的,以确保它的内容一定是这个结构。

快速解压内含嵌套列表的列表,并同时将嵌套列表内的值也赋值给不同的变量

>>> result = [1, 2, [3, 4], 5]>>> [a, b, [c, d], e] = result>>> a1>>> b2>>> c3>>> d4>>> e5

这个操作也是偶尔会在处理一些私有协议时用到,你可以通过这个操作快速地将列表中的值赋值给不同的变量再进行处理,非常方便。

如果你只需要嵌套列表中的某个开头的值,其余的不需要怎么办呢?可以像这样:

>>> result = [1, 2, [3, 4, 5]]>>> [a, b, [c, *_]] = result>>> a1>>> b2>>> c3

总之就是和前面的操作一样,使用星号来处理后面的多个值,并将它们赋值给下划线这种临时变量抛弃。

注:下划线变量的用途和含义可以自行通过搜索引擎搜索一下,网上有很多文章提到,这里就不再赘述了。

遍历嵌套且长短不一的列表时,按头、尾切割,并将它们分别赋值给两个变量

>>> result = [["items", "item1", "item2", "item3"], ["status", 1]]>>> for key, *values in result:... print(key)... print(values)...>>> items['item1', 'item2', 'item3']>>> status[1]

这个操作偶尔会在处理一些私有协议或者奇葩平台的接口时用到,就是对方给你返回的内容可能是这么一个嵌套列表,子列表的第一个值是key、后面的部分是value,然后有些奇葩点的平台可能连子列表的顺序都不相同。

这种时候如果用这个操作去取key和value的话,就会方便很多,你不需要管它的value到底有多少个,也不需要按下标0去取嵌套列表中的key,你只需要直接这么for一下然后处理key和value就完事了。

>>> {key:values for key, *values in result}{'items': ['item1', 'item2', 'item3'], 'status': [1]}

甚至你还可以直接把这个代码写成一行,直接将它们转成字典再做后续的处理。

快速解压一个字典,并将它里面的key和value们分别赋值给不同的变量

>>> a = {"key1": "value1", "key2": "value2", "key3": "value3"}>>> (key1, value1), (key2, value2), (key3, value3) = a.items()>>> key1'key1'>>> value1'value1'>>> key2'key2'>>> value2'value2'

这个操作的用途也是对于爬虫工程师和后端工程师而言会比较常见,比如说:

你需要提取一个接口返回的带有状态码、状态信息和data的内容,并且你需要判断一下状态码是不是代表请求成功的那个,这时候如果是一个一个通过key去取值、赋值的话就会很麻烦,但如果你用这个操作的话,就可以快速解决。

可能光是这么说不太直观,看一段样例代码吧:

>>> result = {"code": 200, "data": {"balabala": 111}, "msg": None}>>> (_, code), (_, data), (_, msg) = result.items()>>> code200>>> data{'balabala': 111}>>> msg>>>

当然这个操作也不能乱用,在使用这个操作时,你需要确保字典中key的顺序严格一致,否则就可能会出现提取到错误内容的情况,所以提取之前为了防止顺序错乱,可以先按key做个排序,以确保顺序是严格一致的。

然后字典中的内容是否会有变化也是需要考虑的,如果你写的代码需要非常严谨,那就还是老老实实地按key一个一个取吧,毕竟如果这里面多了一个key在中间位置,取到的东西就会完全不同。

动态构建出Python中的各种运算符

这个操作是基于Python标准库之一的operator库做的,它可以实现各种比较运算、逻辑运算、数学运算、序列运算。由于这个库里的东西比较多,所以我们这里看个图就好,不多赘述了,大家可以后面自己看看官方文档。

然后用途的话,举个例子,比如你是一个爬虫工程师,你想弄一个纯图形化界面采集数据的工具,然后这时候你可能会碰到某些平台(网站和APP的统称)的内容较为复杂,有些字符串需要按下标取出特定部分的内容,这时候你就可以通过operator.getitem(str, slice(start, end))来取,这里的start和end就直接在工具的界面上填写或选择出来就好了。

>>> import operator>>> a = "666111666">>> operator.getitem(a, slice(3, 6))'111'

动态创建函数

有时候你可能会碰到类似这样的特殊情况:你有一些不同的值需要通过处理方式相同的函数进行处理,但由于条件限制你还不能将这个函数归纳为一个并通过传参的方式进行处理,只能是写出多个不同名称的函数来分别处理。

或者你可能就是单纯有个需求需要动态创建一个临时函数来使用。

这时候如果使用这个操作的话,就可以很轻松地解决这个问题,只需要像这样就可以动态地创建出一个函数了:

>>> from types import FunctionType>>>>>> func = FunctionType(compile(... ("def func():\n"... " print(1)\n"... " return 2"),... "",... "exec"... ).co_consts[0], globals())>>> print(func())12

注:这里面用括号包起来的字符串会自动进行拼接,属于Python中多行字符串的写法之一,优点是不会因为像三个引号那样会因为缩进导致字符串内容受影响。如果想了解更多可以自行查看Python官方文档,里面的字符串部分有讲这个小技巧。

我们还可以对里面那个函数代码字符串进行动态生成(比如用format),以实现对函数名和内容的修改,甚至我们还可以通过使用像Jinja这种模板渲染库来实现更方便的函数代码生成。

像我前段时间写那篇发票整理工具的文章时,就碰到了前面说的那个特殊情况,由于Django Admin的那个action函数的参数是固定的,并且如果需要传参给action函数的话就需要通过中间页来实现,而我既不想弄中间页、又有好几个不同的参数需要分别处理,于是就直接采用动态创建函数的方式来解决了。

动态导入

有时候你可能会有一些扩展代码之类的需要在运行时动态地被导入,这时候你就可以用上这个操作了,比如说我们需要导入operator这个库:

>>> import importlib>>>>>> module = importlib.import_module("operator")

然后这个module变量就是被导入后的模块名称了,我们可以直接和正常导入时一样使用,比如我们要调用它的add函数:

>>> module.add(1, 1) # 加法运算符2

动态调用

有时候你在动态导入之后,还会需要进行动态调用,这时候你就可以这样:

>>> import importlib>>>>>> module = importlib.import_module("operator")>>> func = getattr(module, "add")>>> func(1, 1)2

当然,在使用动态创建、动态导入、动态调用这种比较Hack的操作的时候,一定要注意安全问题,就是如果你在使用时有部分参数是需要用户输入的的话,就一定要对输入内容进行检查,以免被利用来直接执行危险代码。

比如说你提供了一个动态创建函数的功能,如果没有检查内容的话,可能有些比较坏的人直接就通过os库之类的来调用命令行把你的机子给黑了,非常危险。

python之禅星号_那些用起来很爽,但用不好可能会被人打的Python骚操作相关推荐

  1. 那些用起来很爽,但用不好可能会被人打的Python骚操作

    这是作者 (Loco)在PyCon China 2020 上海场闪电演讲内容的文字版本.快速将两个分别存放有key和value的列表合并成一个字典 a = [ "key1", &q ...

  2. python之禅 中文_《Python之禅》中对于Python编程过程中的一些建议

    <Python之禅>中对于Python编程过程中的一些建议 来源:中文源码网    浏览: 次    日期:2018年9月2日 [下载文档:  <Python之禅>中对于Pyt ...

  3. python之禅星号_Python基础1

    介绍Python基础,包括变量和简单数据类型.列表基础.操作列表.if语句.字典.输入函数和while循环 在文件名和文件夹名中,最好使用小写字母,并使用下划线来表示空格,因为这是Python采用的命 ...

  4. python之禅星号_Python之禅

    在Python交互式解释器中输 入import this就会显示Tim Peters的The Zen of python 读一读Python之禅,你就明白Python为什么如此吸引人. >> ...

  5. python pca主成分_超越“经典” PCA:功能主成分分析(FPCA)应用于使用Python的时间序列...

    python pca主成分 FPCA is traditionally implemented with R but the "FDASRSF" package from J. D ...

  6. java和python都要掌握_如果两者都决定要学的话,先学Java还是Python?

    先后顺序不关键,要推荐的话推荐先Python. 如果说学过Java学Python会容易一点,那么反过来也一样.不是说会难一点的语言再学简单一点的语言就简单一点,而是会编程的话学简单一点的语言会比学复杂 ...

  7. 为什么python不需要编译_为什么我用Go写机器学习部署平台,而偏偏不用Python?...

    [新智元导读]虽然在机器学习中,Python已经无孔不入.但Python并不是全能之神手中的魔杖可以为所欲为.很多情况下其实用Python的效果并不如其他语言,比如Go更好,甚至可能更糟.本文介绍了为 ...

  8. 运维学python用不上_运维朋友们,别再问需不需要学 Python 了!

    运维人员需不需要学开发?需不需要学 Python?PythonN 和 Shell 有什么区别?天天问这种好水的问题,我实在受不了,决定帮大家扫扫盲. 现阶段,掌握一门开发语言已经成为高级运维工程师的必 ...

  9. python vba excel课程_【Python3+VBA】在Excel中生成小姐姐|python3教程|python入门|python教程...

    https://www.xin3721.com/eschool/pythonxin3721/ 本文转载至知乎ID:Charles(白露未晞)知乎个人专栏 下载W3Cschool手机App,0基础随时随 ...

最新文章

  1. 动手学深度学习笔记一线性回归
  2. 利用SIFT和RANSAC算法(openCV框架)实现物体的检测与定位,并求出变换矩阵(findFundamentalMat和findHomography的比较)
  3. Hive的基本操作-数据库的创建和删除
  4. LeetCode 1955. 统计特殊子序列的数目
  5. 苹果侧边滑动返回_后置指纹、侧边指纹、屏幕指纹到底哪个更好用? 来讨论一下!...
  6. odbc如何连oracle数据库,不安装Oracle如何连数据库(odbc驱动)
  7. 在Typescript中使用ASP.NET Core SignalR和React创建实时应用程序
  8. 判断new出来的对象里面值为null
  9. 【A星算法】--第四篇(A星算法)
  10. 安全防御(四)--- 恶意软件及其特征、分类、免杀技术,反病毒技术,反病毒网关工作过程及其配置
  11. PandoraBox潘多拉多线多播
  12. cto 技能图谱_成为CTO的关键技能是什么?
  13. ESP32-C3入门教程 系统篇①——FreeRTOS系统时钟Tick
  14. 计算机基础知识综合参考书,计算机基础知识综合参考-20210411123539.pdf-原创力文档...
  15. 天气显示服务器不可用,Windows7系统小工具天气不显示提示所在的地区无法使用服务...
  16. FinClip小程序+Rust(二):环境搭建
  17. android获取定位并标点,Android Studio 中实现高德定位并获取相应信息
  18. [前端笔记037]vue2之vuex
  19. 图像归一化 normalization
  20. 微信8.0来了,可以加1w人好友,微商必看!!!

热门文章

  1. iOS中的中间人-NSURLProtocol 的原理和使用实例
  2. 对DNN的一些高层架构设想
  3. Ubuntu 8.04 LTS的离线升级包运用教程
  4. 《数据结构》双链循环线性表
  5. 泰安机器人比赛_泰安学子在省青少年机器人竞赛上揽8个一等奖
  6. java数组给名字排序_用Java给数组排序
  7. MySQL update For_mysql SELECT FOR UPDATE语句使用示例
  8. 数据中台 画像标签_数据中台实战:如何通过标签平台圈出产品高价值用户?...
  9. java中子类怎样调用父类的属性_java的继承、重载(overload)、覆盖(override)的总结...
  10. 早秋精品电商男装页面\海报设计PSD模板