地道的 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里挑出来的奇数的元素。高逼格吗?一行搞定!因为,这里的循环判断语句不是给 机器 看的,而是让 人 来理解的。从左向右读就可以了:列表中包含元素a一方面来自于列表A,同时它符合除以2余数不为0的条件。

说了这么多,列位看官可以动手改改例子1,让它得到它应得逼格了吗?

def reach_age_limit(personal_info):
    name, age, sex, yow, salary, tax, bonus = personal_info>split(‘,‘)
    return f( sex == ‘Male‘ and int(age) > 60 ) or
          ( sex == ‘Female‘ and int(age) > 55 )

def calculate_person(personal_info):
    name, age, sex, yow, salary, tax, bonus = personal_info>split(‘,‘)
    return  int(yow) * ( int(salary) - int(tax) + int(bonous) ) * 0.9

def get_name(personal_info):
    name, age, sex, yow, salary, tax, bonus = personal_info>split(‘,‘)
    return name

def count_person():
    with open(‘data.csv‘) as f:
        data = f.read()
    target_persons = [ d for d in data.splitlines() if reach_age_limit(d) ]

    groups = {}
    for person in target_persons:
        groups.setdefault(get_name(person),[]).append(calculate_person(person))

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

这就可以了吗?还有别的方法吗?还有一个更高逼格的例子:

def count_person():
    with open(‘data.csv‘) as f:
        data = f.read()

    groups = {get_name(person):caculate_person(person)
              for person in data.splitlines()
              if reach_age_limit(person)}

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

抽取出来的三个函数,如果聚集到某个类中,就更高 perfect 了。

例子讲评完了,本文就该结束了吗?不,不,不,让你猜到结局,小编的要蛋痛了。。。

现在业界火热的函数式编程,Python 怎么支持的? 一定有蛋痛的 Python 人做了些什么,让我们可以更高逼格一些。


Cache

从下面的例子开始,

def web_lookup(url, cache={}):
    if url not in cache:
        cache[url] = urllib.urlopen(url).read()
    return cache[url]

这个函数有一个功能:打开指定的url;还有一个附属功能:缓存之前打开过的url;严格来说,这违反了单一职责原则;蛋痛的 Python 人给出了如下的方案:

@cache
def web_lookup(url)
    return urllib.urlopen(url).read()

def cache(func)
    saved = {}
    @wraps
    def new_func(*args):
        if args not in saved:
            saved[args] = func(*args)
        return saved[args]
    return new_func

cache 函数里,针对被cache修饰的函数,做了一个针对输入参数和返回值的缓存,产生的新函数被返回。这样,每次web_lookup被调用的时候,实际上被调用的是输入、输出被缓存后的新函数,而不是字面原来的那样的函数。Python 支持同名函数,看官们还记得吗?


Combine

假设实现一个计算器,接收到按键序列28++32+++32+39,使用 Python 得出计算结果

expr, res = ‘28++32+++32+39‘, 0
for token in expr.split(‘+‘):
    if token:
        res += int(token)

这是 C 语言逻辑下的代码,而 Python 中蛋痛的人们完全可以不适用任何新增变量,直接使用三个函数进行组合:

res = sum(map(int, filter(bool, expr.split(‘+‘))))

第一个函数filter(pred, seq) –> [t for t in seq if pred(t)],剔除不符合bool条件的元素;

第二个函数map(fun, seq) –> [func(t) for t in seq],这个实际上就是数学上的映射的定义,对于机器来说就是循环,但是 人 更关注的是映射关系(非常高层次的领域),这样编译器更容易去优化(例如并行计算所有的序列)。

第三个函数sum,顾名思义就是对列表里所有元素,求和。

此时小编已满脑数学名词了,程序语言已经完全被抛弃:先剔除列表中的空串,然后映射字符串为整数,最后对所有元素求和。


All

之前介绍循环时用过一个例子,实际上它还可以更高逼格的实现:

ages = [42, 21, 18, 33, 19]
if all(map(lambda a:a>=18, ages)):
   print ‘All are adults!‘

lambda用来构造一个函数,输入参数a,返回a>=18;

map将ages里所有元素映射为由True/False组成的列表;

all返回列表内所有元素是否都为True

看到这里,列位看官有感觉了吗?循环是给 机器 使用的绝低逼格东东,Python 程序员们应该疏远它,避免它。

现在真的要说再见了,最后一句:

Python 装X之路其修远兮,吾辈将上下而求索。

时间: 2024-08-05 00:12:19

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

python 人脸检测 +python 二维码检测

从官网下载opencv 目录结构如图 在samples中有丰富的示例 应为我的系统中已经安装好opepncv-python,可直接运行 会得到结果: 人脸检测代码如下 #!/usr/bin/env python ''' face detection using haar cascades USAGE: facedetect.py [--cascade <cascade_fn>] [--nested-cascade <cascade_fn>] [<video_source>

Python 二、Python过程型程序设计快速入门

一.数据结构 程序=数据结构+算法 数据结构: 通过某种方式(例如对元素进行编号)组织在一起的数据元素的集合,这些数据元素可以是数字或者字符,甚至可以是其它的数据结构. python的最基本数据结构是序列 序列中的每个元素被分配一个序号(即元素的位置),也陈为索引:索引从0开始编号 python包含6中内建的数据序列:列表.元祖.字符串.Unicode字符串.buff对象和xrange对象 二.python的关键要素 基本数据类型 对象引用 组合数据类型 逻辑操作符 控制流语句 算术操作符 输入

Python 二、Python对象类型及其运算

一.Python对象的相关术语 Python中一切皆对象,python程序中保存的所有数据都是围绕对象这个概念展开的:所有的对象都是由类实例化而来的,只不过这些类有些是python内置的类:例如,整数和浮点数,字符串都是由python内置的类实例化而来的.除此之外用户还可以自定义类型,就是类. python程序中存储的所有数据都是对象 每个对象都有一个身份.一个类型和一个值 例如,school="MaGe Linux"会以"MaGe Linux"创建一个字符串对象,

python 二维数组90°旋转

题目: 使用python生成一个4×4二维数组并将其顺时针旋转90° 源码如下: import random datarow=[] data=[] for i in range(4):     for j in range(4):         datarow.append(random.randint(10,80))     data.append(datarow)     datarow = [] print("data") for k in data:     print(k)

hack with python(二)

环境:dvwa 1.7数据库: mysql前置知识:  1.阅读了关于sql注入基础的两个博文并自己动手实践过(一)(二)    2.阅读了hack with python(一) 一.学习web安全的过程并不总是充满快乐,有时还有点小枯燥(1)那这样我们,先来玩个小游戏吧!猜数字,看一看你能多少次猜出数字 #! /usr/bin/python #A game to a guess a number between 1 and 100 #if the times you guess is less

python二维数组

今天..好多不会的,慢慢补充 1.python的二维数组初始化 s = [[0 for i in range(3)]for i in range(3)] 这样就初始了一个3*3的二维数组 = [[0 for in range(col_numbers)] for i in range(rows_numbers)] 2. with open('test.txt','rb') as f: s = f.readline() s的结尾是带着\r\n的 所以使用 s.strip('\r\n') strip参

【转载】不得不知道的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二次学习之二(第一天学到的一个重点pickle模块)

ython pickle模块作用是持久化的储存数据. 经常遇到在Python程序运行中得到了一些字符串.列表.字典等数据,想要长久的保存下来,方便以后使用,而不是简单的放入内存中关机断电就丢失数据.python模块大全中的Pickle模块就派上用场了,它可以将对象转换为一种可以传输或存储的格式. 一.Pickle对象串行化 Pickle模块将任意一个Python对象转换成一系统字节的这个操作过程叫做串行化对象.二.Pickle与CPickle对比 前者是完全用Python来实现的模块,这个CPi

python二维码生成器

周小董简书主页二维码.png 周小董博客主页二维码.png 现在,我们生活中到处可以看到二维码.它有啥好处呢?它具有信息容量大.可靠性高.可表示汉字及图象多种文字信息.保密防伪性强等优点. 我们生成的东西一般都在电脑上.如果弄到移动设备上,用到最多的是扫码.在移动设备浏览器中输入URL明显没有扫描二维码方便. 就是这个: python 有qrcode库,很容易就生成二维码.现在在需要使用Python图像库的时候一般是用 Pillow 模块代替PIL.安装非常简单: pip install pil