在Python3中初学者应会的一些基本的提升效率的小技巧


Posted in Python onMarch 31, 2015

有时候我反问我自己,怎么不知道在Python 3中用更简单的方式做“这样”的事,当我寻求答案时,随着时间的推移,我当然发现更简洁、有效并且bug更少的代码。总的来说(不仅仅是这篇文章),“那些”事情总共数量是超过我想象的,但这里是第一批不明显的特性,后来我寻求到了更有效的/简单的/可维护的代码。
字典

字典中的keys()和items()

你能在字典的keys和items中做很多有意思的操作,它们类似于集合(set):

aa = {‘mike': ‘male', ‘kathy': ‘female', ‘steve': ‘male', ‘hillary': ‘female'}
 
bb = {‘mike': ‘male', ‘ben': ‘male', ‘hillary': ‘female'}
 
aa.keys() & bb.keys() # {‘mike', ‘hillary'} # these are set-like
aa.keys() - bb.keys() # {‘kathy', ‘steve'}
# If you want to get the common key-value pairs in the two dictionaries
aa.items() & bb.items() # {(‘mike', ‘male'), (‘hillary', ‘female')}

太简洁啦!

在字典中校验一个key的存在

下面这段代码你写了多少遍了?

dictionary = {}
for k, v in ls:
  if not k in dictionary:
    dictionary[k] = []
  dictionary[k].append(v)

这段代码其实没有那么糟糕,但是为什么你一直都需要用if语句呢?

from collections import defaultdict
dictionary = defaultdict(list) # defaults to list
for k, v in ls:
  dictionary[k].append(v)

这样就更清晰了,没有一个多余而模糊的if语句。

用另一个字典来更新一个字典

from itertools import chain
a = {‘x': 1, ‘y':2, ‘z':3}
b = {‘y': 5, ‘s': 10, ‘x': 3, ‘z': 6}
 
# Update a with b
c = dict(chain(a.items(), b.items()))
c # {‘y': 5, ‘s': 10, ‘x': 3, ‘z': 6}

这样看起来还不错,但是不够简明。看看我们是否能做得更好:

c = a.copy()
c.update(b)

更清晰而且更有可读性了!

从一个字典获得最大值

如果你想获取一个字典中的最大值,可能会像这样直接:

aa = {k: sum(range(k)) for k in range(10)}
aa # {0: 0, 1: 0, 2: 1, 3: 3, 4: 6, 5: 10, 6: 15, 7: 21, 8: 28, 9: 36}
max(aa.values()) #36

这么做是有效的,但是如果你需要key,那么你就需要在value的基础上再找到key。然而,我们可以用过zip来让展现更扁平化,并返回一个如下这样的key-value形式:

max(zip(aa.values(), aa.keys()))
# (36, 9) => value, key pair

同样地,如果你想从最大到最小地去遍历一个字典,你可以这么干:

sorted(zip(aa.values(), aa.keys()), reverse=True)
# [(36, 9), (28, 8), (21, 7), (15, 6), (10, 5), (6, 4), (3, 3), (1, 2), (0, 1), (0, 0)]

在一个list中打开任意数量的items

我们可以运用*的魔法,获取任意的items放到list中:

def compute_average_salary(person_salary):
  person, *salary = person_salary
  return person, (sum(salary) / float(len(salary)))
 
person, average_salary = compute_average_salary([“mike”, 40000, 50000, 60000])
person # ‘mike'
average_salary # 50000.0

这不是那么有趣,但是如果我告诉你也可以像下面这样呢:

def compute_average_salary(person_salary_age):
  person, *salary, age = person_salary_age
  return person, (sum(salary) / float(len(salary))), age
 
person, average_salary, age = compute_average_salary([“mike”, 40000, 50000, 60000, 42])
age # 42

看起来很简洁嘛!

当你想到有一个字符串类型的key和一个list的value的字典,而不是遍历一个字典,然后顺序地处理value,你可以使用一个更扁平的展现(list中套list),像下面这样:

# Instead of doing this
for k, v in dictionary.items():
  process(v)
 
# we are separating head and the rest, and process the values
# as a list similar to the above. head becomes the key value
for head, *rest in ls:
  process(rest)
 
# if not very clear, consider the following example
aa = {k: list(range(k)) for k in range(5)} # range returns an iterator
aa # {0: [], 1: [0], 2: [0, 1], 3: [0, 1, 2], 4: [0, 1, 2, 3]}
for k, v in aa.items():
  sum(v)
 
#0
#0
#1
#3
#6
 
# Instead
aa = [[ii] + list(range(jj)) for ii, jj in enumerate(range(5))]
for head, *rest in aa:
  print(sum(rest))
 
#0
#0
#1
#3
#6

你可以把list解压成head,*rest,tail等等。

Collections用作计数器

Collections是我在python中最喜欢的库之一,在python中,除了原始的默认的,如果你还需要其他的数据结构,你就应该看看这个。

我日常基本工作的一部分就是计算大量而又不是很重要的词。可能有人会说,你可以把这些词作为一个字典的key,他们分别的值作为value,在我没有接触到collections中的Counter时,我可能会同意你的做法(是的,做这么多介绍就是因为Counter)。

假设你读的python语言的维基百科,转化为一个字符串,放到一个list中(标记好顺序):

import re
word_list = list(map(lambda k: k.lower().strip(), re.split(r'[;,:(.s)]s*', python_string)))
word_list[:10] # [‘python', ‘is', ‘a', ‘widely', ‘used', ‘general-purpose', ‘high-level', ‘programming', ‘language', ‘[17][18][19]']

到目前为止看起来都不错,但是如果你想计算这个list中的单词:

from collections import defaultdict # again, collections!
dictionary = defaultdict(int)
for word in word_list:
  dictionary[word] += 1

这个没有那么糟糕,但是如果你有了Counter,你将会节约下你的时间做更有意义的事情。

from collections import Counter
counter = Counter(word_list)
# Getting the most common 10 words
counter.most_common(10)
[(‘the', 164), (‘and', 161), (‘a', 138), (‘python', 138),
(‘of', 131), (‘is', 102), (‘to', 91), (‘in', 88), (‘', 56)]
counter.keys()[:10] # just like a dictionary
[‘', ‘limited', ‘all', ‘code', ‘managed', ‘multi-paradigm',
‘exponentiation', ‘fromosing', ‘dynamic']

很简洁吧,但是如果我们看看在Counter中包含的可用的方法:

dir(counter)
[‘__add__', ‘__and__', ‘__class__', ‘__cmp__', ‘__contains__', ‘__delattr__', ‘__delitem__', ‘__dict__',
‘__doc__', ‘__eq__', ‘__format__', ‘__ge__', ‘__getattribute__', ‘__getitem__', ‘__gt__', ‘__hash__',
‘__init__', ‘__iter__', ‘__le__', ‘__len__', ‘__lt__', ‘__missing__', ‘__module__', ‘__ne__', ‘__new__',
‘__or__', ‘__reduce__', ‘__reduce_ex__', ‘__repr__', ‘__setattr__', ‘__setitem__', ‘__sizeof__',
‘__str__', ‘__sub__', ‘__subclasshook__', ‘__weakref__', ‘clear', ‘copy', ‘elements', ‘fromkeys', ‘get',
‘has_key', ‘items', ‘iteritems', ‘iterkeys', ‘itervalues', ‘keys', ‘most_common', ‘pop', ‘popitem', ‘setdefault',
‘subtract', ‘update', ‘values', ‘viewitems', ‘viewkeys', ‘viewvalues']

你看到__add__和__sub__方法了吗,是的,Counter支持加减运算。因此,如果你有很多文本想要去计算单词,你不必需要Hadoop,你可以运用Counter(作为map)然后把它们加起来(相当于reduce)。这样你就有构建在Counter上的mapreduce了,你可能以后还会感谢我。

扁平嵌套lists

Collections也有_chain函数,其可被用作扁平嵌套lists

from collections import chain
ls = [[kk] + list(range(kk)) for kk in range(5)]
flattened_list = list(collections._chain(*ls))

同时打开两个文件

如果你在处理一个文件(比如一行一行地),而且要把这些处理好的行写入到另一个文件中,你可能情不自禁地像下面这么去写:

with open(input_file_path) as inputfile:
  with open(output_file_path, ‘w') as outputfile:
    for line in inputfile:
      outputfile.write(process(line))

除此之外,你可以在相同的一行里打开多个文件,就像下面这样:

with open(input_file_path) as inputfile, open(output_file_path, ‘w') as outputfile:
  for line in inputfile:
    outputfile.write(process(line))

这样就更简洁啦!
从一堆数据中找到星期一

如果你有一个数据想去标准化(比如周一之前或是之后),你也许会像下面这样:

import datetime
previous_monday = some_date - datetime.timedelta(days=some_date.weekday())
# Similarly, you could map to next monday as well
next_monday = some_date + date_time.timedelta(days=-some_date.weekday(), weeks=1)

这就是实现方式。
处理HTML

如果你出于兴趣或是利益要爬一个站点,你可能会一直面临着html标签。为了去解析各种各样的html标签,你可以运用html.parer:
 

from html.parser import HTMLParser
 
class HTMLStrip(HTMLParser):
 
  def __init__(self):
    self.reset()
    self.ls = []
 
  def handle_data(self, d):
    self.ls.append(d)
 
  def get_data(self):
    return ‘'.join(self.ls)
 
  @staticmethod
  def strip(snippet):
    html_strip = HTMLStrip()
    html_strip.feed(snippet)
    clean_text = html_strip.get_data()
    return clean_text
 
snippet = HTMLStrip.strip(html_snippet)

如果你仅仅想避开html:
 

escaped_snippet = html.escape(html_snippet)
 
# Back to html snippets(this is new in Python 3.4)
html_snippet = html.unescape(escaped_snippet)
# and so forth ...
Python 相关文章推荐
python中 ? : 三元表达式的使用介绍
Oct 09 Python
python解析html开发库pyquery使用方法
Feb 07 Python
python将MongoDB里的ObjectId转换为时间戳的方法
Mar 13 Python
python常用函数详解
Sep 13 Python
django manage.py扩展自定义命令方法
May 27 Python
对PyQt5中树结构的实现方法详解
Jun 17 Python
PyQt4 treewidget 选择改变颜色,并设置可编辑的方法
Jun 17 Python
Pandas0.25来了千万别错过这10大好用的新功能
Aug 07 Python
python selenium 执行完毕关闭chromedriver进程示例
Nov 15 Python
Python 使用 prettytable 库打印表格美化输出功能
Dec 26 Python
python如何导入依赖包
Jul 13 Python
Python如何定义接口和抽象类
Jul 28 Python
使用IronPython把Python脚本集成到.NET程序中的教程
Mar 31 #Python
提升Python程序运行效率的6个方法
Mar 31 #Python
用Python从零实现贝叶斯分类器的机器学习的教程
Mar 31 #Python
利用Python的Flask框架来构建一个简单的数字商品支付解决方案
Mar 31 #Python
用Python进行基础的函数式编程的教程
Mar 31 #Python
python使用多线程不断刷新网页的方法
Mar 31 #Python
Python新手实现2048小游戏
Mar 31 #Python
You might like
php截取字符串并保留完整xml标签的函数代码
2013/02/06 PHP
php启用zlib压缩文件的配置方法
2013/06/12 PHP
php双层循环(九九乘法表)
2017/10/23 PHP
Laravel实现ApiToken认证请求
2019/10/14 PHP
laravel 实现上传图片到本地和前台访问示例
2019/10/21 PHP
javascript网页关闭时提醒效果脚本
2008/10/22 Javascript
jquery 学习之二 属性 文本与值(text,val)
2010/11/25 Javascript
推荐40个简单的 jQuery 导航插件和教程(下篇)
2012/09/14 Javascript
回车直接实现点击某按钮的效果即触发单击事件
2014/02/27 Javascript
5个可以帮你理解JavaScript核心闭包和作用域的小例子
2014/10/08 Javascript
js中setTimeout()与clearTimeout()用法实例浅析
2015/05/12 Javascript
tuzhu_req.js 实现仿百度图片首页效果
2015/08/11 Javascript
使用Chart.js图表库制作漂亮的响应式表单
2015/10/28 Javascript
JS代码实现百度地图 画圆 删除标注
2016/10/12 Javascript
分类解析jQuery选择器
2016/11/23 Javascript
JS实现搜索关键词的智能提示功能
2017/07/07 Javascript
Node.js系列之安装配置与基本使用(1)
2019/08/30 Javascript
Antd下拉选择,自动匹配功能的实现
2020/10/24 Javascript
基于vuex实现购物车功能
2021/01/10 Vue.js
在Python的Django框架下使用django-tagging的教程
2015/05/30 Python
Python实现Mysql数据库连接池实例详解
2017/04/11 Python
python初学之用户登录的实现过程(实例讲解)
2017/12/23 Python
python+opencv实现高斯平滑滤波
2020/07/21 Python
Python统计一个字符串中每个字符出现了多少次的方法【字符串转换为列表再统计】
2019/05/05 Python
python实现随机漫步方法和原理
2019/06/10 Python
html5 Canvas画图教程(7)—canvas里画曲线之quadraticCurveTo方法
2013/01/09 HTML / CSS
prAna官网:瑜伽、旅行和冒险服装
2019/03/10 全球购物
运动会解说词100字
2014/01/31 职场文书
元旦晚会主持词
2014/03/24 职场文书
大学生社会实践自我鉴定
2014/03/24 职场文书
新教师个人总结
2015/02/06 职场文书
教师年终个人总结
2015/02/11 职场文书
2015年学校办公室工作总结
2015/05/26 职场文书
关于Python中*args和**kwargs的深入理解
2021/08/07 Python
Windows server 2012 R2 安装IIS服务器
2022/04/29 Servers
python 镜像环境搭建总结
2022/09/23 Python