地道的 Python(一)

作者: Zhang Yang

逼格

水果公司的一句 “The bigger than bigger” 广告词,使得逼格进入了大众的视野。内置逼格神器的程序猿们的内心一定是向往着更高的逼格。试问自己心里是否憧憬着这样一个场景:

当你随手写下一行代码的时候,旁边的人不可思议的睁大眼睛,表示着原来代码可以这样写?

这是怎样一种装X之旅。Python 可以帮助你实现这样的愿望。

Python 对于外行们来说,它都非常容易上手。同时,对于我们这些使用C语言开蒙,甚至工作中主要使用C语言的程序员们来说,使用它却有着天然的障碍。这让苦逼的程序员们如何在外行面前保持尊严?别着急,请接着看。


惯用语

学习过英语的大家都知道,我们现在说的英语(English),实际上是 Chinglish,而印度人则说着一种叫 Hinglish 的语言,这也是为什么我们听好莱坞原声大片的时候,要比听中国人说英语要困难得多。每一种语言,每一群人,都会有自己的习惯用法 – 惯用语。程序语言也是同样的道理,特别是众多的高级语言,它们都是有着自己独特的那部分东西,这是它们被需要或者不需要的原因。就像蹩脚的程序员,用 C语言的习惯写 C++ 代码一样,编译执行都没有问题,但是你干嘛不直接写 C 文件?!

我们来看一看下面这片代码:

def count_person_c()
    f = open(‘data.csv‘)
    try:
        data = f.read()
    finally:
        f.close()

    groups = {}
    lines = data.splitlines()
    for i in xrange(len(lines)):
        name = lines[i].split(‘,‘)[0]
        age = lines[i].split(‘,‘)[1]
        sex = lines[i].split(‘,‘)[2]
        yow = lines[i].split(‘,‘)[3]
        salary = lines[i].split(‘,‘)[4]
        tax = lines[i].split(‘,‘)[5]
        bonus = lines[i].split(‘,‘)[6]

        if( sex == ‘Male‘ and int(age) > 60 ) or
          ( sex == ‘Female‘ and int(age) > 55 ):
            person = int(yow) * ( int(salary) - int(tax) + int(bonous) ) * 0.9
            if name not in groups:
                groups[name] = []
            groups[name].append(person)

    for key in groups:
        print key, ‘--->‘, groups[key]

这是使用 Python 的语法完成的,还可以使用 Python 解释器执行。但是,请再仔细看一遍,是否觉着似曾相识?这块代码除了使用了 Python 的原生字典类型,还有什么是 Python 的东西?这样的逼格得和马里亚纳海沟差不多的高度了。

要追求更高的逼格, Python 从来都是从 人 而不是 机器 的角度来思考问题的,后面我们会不断见到这样的例子。

蛋痛定律

如果有一件事让你蛋痛,那么一定已经有蛋痛人帮助你完成它。


赋值

例子中最亮瞎钛合金眼球的就是那 7 行整齐的赋值语句了。从机器的角度看,它们是一个又一个的赋值语句,非常完美。但是从 人 的角度看,这些东西看起来会让人蛋痛:明明是从同一块数据中抠出来的数值,为什么程序语言要求要用这么行来获取它?实际上,这样的代码,在 C 语言以及其他很多语言中,被认为是不可避免的,程序员们能做的就是让它们看起来比较整齐,别太疼而已。

蛋痛的 Python 人并不认为这应该是很多步的赋值,而应该是一个拆包(unpacking)的语句,所以应该一行就完全实现,如下:

name, age, sex, yow, salary, tax, bonus = lines[i].split(‘,‘)

这里说一句小编的个人感受,如果 Python 的代码里常常看到形如 name[i], name[1], name[key]的形式,说明楼主的 机器 之毒已经相当深厚了。一定要消灭它们,且一定有办法消灭它们,逼格实在够low。

回到正文,类似的例子,程序员们在学习计算机语言的的时候,一定都被老师要求写过一段程序,来交换两个变量的值;蛋痛的程序员们有时候还被要求不能使用第三个变量缓存。这样蛋痛的事情,依然还在很多学校里不断地发生。Python 里蛋痛的人们认为数值交换,就应该是一个简单的语句实现,超过一行以上的语句就是在侮辱自己的智商,所以在 Python 里我们可以这样:

a, b = b, a

循环

蛋痛的程序员们在学习 C 语言的时候,就被暗示: 循环是需要通过索引值得+1/-1完成数值递推的,所以i, j, k成为了程序中最最常见的变量名,大家几乎一看到它们就会条件反射般认为,它们应该是某个循环中的索引(Clean Code一书就明确这么说的)。但实际上,循环遍历一溜东东并不必然需要索引,它反而会带来一些混乱。几乎是写每个循环是都要额外考虑:索引到底是从0开始,还是从1开始;结束的地方是否要-1。看官们回想一下,在做线性代数家庭作业中向量计算的时候,你的脑子里使用过索引吗?是的,不需要,用眼睛看,手指头比划就行了。只是该死的 图灵机 需要索引,看到索引 人 就会蛋痛的。蛋痛的 Python 就这样循环:

 for d in [1, 2, 3, 4]:

变量 a 就是分别会成为1、2、3、4,这里索引是不需要的,会逼着 人 以 机器 的角度思考问题,增加不必要的难度。反对者们一定会说,索引可以让循环以反序遍历。请淡定,如下可以实现4、3、2、1的遍历。

D = [1, 2, 3, 4]
for d in D[::-1]:

尽管这样,蛋痛的事还是会发生,有些时候程序真的需要索引,特别是需要把索引值作为参数给循环体内调用的函数时,怎么办?蛋痛的 Python 还有方案:enumerate(colors),它能返回一对值: 索引, 变量,如下所示。

for i,d in enumerate([1, 2, 3, 4]):

Python 的 for 还有一个神奇的地方,被称为 for-else。程序中,常常有这样的场景:循环遍历某个链表,如果找到想要的成员则立刻返回它的位置,否则一定找完所有元素。

ages = [42, 21, 18, 33, 19]

are_all_adult = True
for age in ages:
    if age < 18:
        are_all_adult = False
        break
if are_all_adult:
    print ‘All are adults!‘

如果是 C 语言,这还是不错的。但是在 Python 看来,这也有让人蛋痛的地方,因为它可以是这样的:

ages = [42, 21, 18, 33, 19]
for age in ages:
    if age < 18:
        break
else
    print ‘All are adults!‘

当循环中的break没有被执行过,最后一次循环会进入到else里执行;蛋痛的人们这它也起了一个蛋痛的名字,更贴切的说法应该是un-break。

当然,Python 还有另一个更高逼格的方法实现这个功能,只需要两行代码,后文会提到。


字典

前面说的都是常见的列表循环,Python 自带的独特的数据类型:字典的循环,变量的值只是字典的键值而没有条目的内容:

for key in groups:
   print key, ‘--->‘, groups[key]

看到groups[key],蛋痛再次袭来。是的,Python 里字典的循环,不应该是这个样子的,它把自己设计成这样:

for key, value in groups.items():
   print key, ‘--->‘, value

是的,就是你看到的这个意思,键值和条目内容是成对返回的;这样还一个可能的额外好处:当字典变得非常庞大的时候,将items()改成interitems(),可以非常有效的改进 Python 的性能,还节约内存,这个叫迭代器,后文会提到。

说到字典,关注下面这片代码:

groups = {}
    ...
    if name not in groups:
        groups[name] = []
    groups[name].append(person)

这是一个 C 程序员写的典型 Python 代码,不但有蛋痛的groups[name],还有多层缩进,判断,赋值空列表,简直蛋痛加三级。根据蛋痛定律,一定有蛋痛的人帮助解决这样的问题:

groups = {}
...
   groups.setdefault(name, []).append(pension)

或者是

groups = defaultdict(list)
...
   groups[name].append(pension)

只有当name作为键值第一次出现时,字典groups会自动调用函数list建立一个空列表;如果已经存在了,则直接调用列表的append行为。小编更喜欢第二种写法,插入的时候代码更简洁明了。现在怎么看,怎么觉得 groups = {} 是在定义变量,蛋痛啊… …

时间: 2024-10-13 11:14:05

地道的 Python(一)的相关文章

地道的 Python(二)

作者: Zhang Yang 列表推导 上文介绍了一个高逼格的创建字典的方法,那列表呢?根据蛋痛定律,它也一定有,但是它被起了一个非常蛋痛的名字,叫列表推导: 先看看这样的代码: li = [] for a in A: if a%2 != 0: li.append(a) 看到代码第一行的时候,小编已经不想再看下去了,是的,这才真正的万变不离 C 语言.蛋痛指数直冲云霄了.Python 里一行就应该搞定它 li = [a for a in A if a%2 != 0] 上文产生的列表包含:从列表A

11个实用但你可能不知道的Python程序库

目前,网上已有成千上万个Python包,但几乎没有人能够全部知道它们.单单PyPi上就有超过47000个包列表. 现在,越来越多的数据科学家开始使用Python,虽然他们从pandas,scikit-learn,numpy中获得了不少好处,但我仍想向他们介绍一些年长且非常实用的Python库.在本文中,我将列一些不太知名的库,即使你是经验丰富的Python的开发者,也值得过来一看. 1) delorean Dolorean是一个非常酷的日期/时间库.类似JavaScript的moment,拥有非

转:11个实用但你可能不知道的Python程序库

原文来自于:http://www.techug.com/11-python-libraries-you-might-not-know 目前,网上已有成千上万个Python包,但几乎没有人能够全部知道它们.单单PyPi上就有超过47000个包列表. 现在,越来越多的数据科学家开始使用Python,虽然他们从pandas,scikit-learn,numpy中获得了不少好处,但我仍想向他们介绍一些年长且非常实用的Python库.在本文中,我将列一些不太知名的库,即使你是经验丰富的Python的开发者

【转载】不得不知道的Python字符串编码相关的知识

原文地址:http://www.cnblogs.com/Xjng/p/5093905.html 开发经常会遇到各种字符串编码的问题,例如报错SyntaxError: Non-ASCII character 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128),又例如显示乱码.由于之前不知道编码的原理,遇到这些情况,就只能不断的用各种编码decode和encode.....今天整理一个pyt

很多人不知道的Python 炫技操作:条件语句的七种写法

首发于公众号:<Python编程时光>一个专注输出高质量 Python开发知识的专栏 有的人说 Python 是一门 入门容易,但是精通难的语言,这一点我非常赞同. Python 语言里有许多(而且是越来越多)的高级特性,是 Python 发烧友们非常喜欢的.在这些人的眼里,能够写出那些一般开发者看不懂的高级特性,就是高手,就是大神. 但你要知道,在团队合作里,炫技是大忌. 为什么这么说呢?我说下自己的看法: 越简洁的代码,越清晰的逻辑,就越不容易出错: 在团队合作中,你的代码不只有你在维护,

90%人不知道的Python炫技操作:合并字典的七种方法

Python 语言里有许多(而且是越来越多)的高级特性,是 Python 发烧友们非常喜欢的.在这些人的眼里,能够写出那些一般开发者看不懂的高级特性,就是高手,就是大神. 但你要知道,在团队合作里,炫技是大忌. 为什么这么说呢?我说下自己的看法: 越简洁的代码,越清晰的逻辑,就越不容易出错: 在团队合作中,你的代码不只有你在维护,降低别人的阅读/理解代码逻辑的成本是一个良好的品德 简单的代码,只会用到最基本的语法糖,复杂的高级特性,会有更多的依赖(如语言的版本) 该篇是「炫技系列」的第二篇内容,

你必须知道的python运维常用脚本!(日常更新)

github地址:https://github.com/opsonly, 上面是一个基于python3.7和django2.1的多人博客系统,喜欢的可以给个star~ 判断是否是一个目录 #!/usr/bin/env python3 # -*- coding: utf-8 -*- # @Time : 2018-12-18 15:16 # @Author : opsonly # @Site : # @File : opsUse.py # @Software: PyCharm import os d

听说你会Python?11篇Python技术热文

<听说你会 Python ?> Python 是世界上最简单的语言?Python 的动态特性可以让其用众多 black magic 去实现一些很舒服的功能,当然这也对我们对语言特性及坑的掌握也变得更严格了.本文总结了Python中的各种难掌握和易踩的"坑". <Python 函数式编程,从入门到?放弃?> 本文使用python介绍了什么是函数式编程,函数式编程的特点,函数式编程的用途,函数式编程相比于命令式编程和面向对象编程的优缺点等. <如何获得 Num

python开发的几个发展方向

以上是我自己所知道的python发展方向,有不对的地方欢迎大家指正.感觉每个方向都很火. 人生苦短,我用python. python开发的几个发展方向