Python代码这样写更优雅(转)

1、变量交换

大部分编程语言中交换两个变量的值时,不得不引入一个临时变量:

>>> a = 1
>>> b = 2
>>> tmp = a
>>> a = b
>>> b = tmp

pythonic

>>> a, b = b, a

2、循环遍历区间元素

for i in [0, 1, 2, 3, 4, 5]:    (print i)

# 或者
for i in range(6):    (print i)

pythonic

for i in xrange(6):    (print i)

xrange 返回的是生成器对象,生成器比列表更加节省内存,不过需要注意的是 xrange 是 python2 中的写法,python3 只有 range 方法,特点和 xrange 是一样的。

3、带有索引位置的集合遍历

遍历集合时如果需要使用到集合的索引位置时,直接对集合迭代是没有索引信息的,普通的方式使用:

colors = ['red', 'green', 'blue', 'yellow']

for i in range(len(colors)):    print (i, '--->', colors[i])

pythonic

for i, color in enumerate(colors):print (i, '--->', color)

4、字符串连接

字符串连接时,普通的方式可以用 + 操作

names = ['raymond', 'rachel', 'matthew', 'roger', 'betty', 'melissa', 'judith', 'charlie']

s = names[0]

for name in names[1:]:    s += ', ' + name
print (s)

pythonic

print (', '.join(names))

join 是一种更加高效的字符串连接方式,使用 + 操作时,每执行一次+操作就会导致在内存中生成一个新的字符串对象,遍历8次有8个字符串生成,造成无谓的内存浪费。而用 join 方法整个过程只会产生一个字符串对象。

5、打开/关闭文件

执行文件操作时,最后一定不能忘记的操作是关闭文件,即使报错了也要 close。普通的方式是在 finnally 块中显示的调用 close 方法。

f = open('data.txt')

try:    data = f.read()
finally:    f.close()

pythonic

with open('data.txt') as f:    data = f.read()

使用 with 语句,系统会在执行完文件操作后自动关闭文件对象。

6、列表推导式

能够用一行代码简明扼要地解决问题时,绝不要用两行,比如

result = []

for i in range(10):    s = i*2    result.append(s)

pythonic

[i*2 for i in xrange(10)]

与之类似的还有生成器表达式、字典推导式,都是很 pythonic 的写法。

7、善用装饰器

装饰器可以把与业务逻辑无关的代码抽离出来,让代码保持干净清爽,而且装饰器还能被多个地方重复利用。比如一个爬虫网页的函数,如果该 URL 曾经被爬过就直接从缓存中获取,否则爬下来之后加入到缓存,防止后续重复爬取。

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

pythonic

import urllib #py2#import urllib.request as urllib 
# py3
def cache(func):    saved = {}    def wrapper(url):        if url in saved:            return saved[url]        else:            page = func(url)            saved[url] = page            return page    return wrapper

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

用装饰器写代码表面上感觉代码量更多,但是它把缓存相关的逻辑抽离出来了,可以给更多的函数调用,这样总的代码量就会少很多,而且业务方法看起来简洁了。

8、合理使用列表

列表对象(list)是一个查询效率高于更新操作的数据结构,比如删除一个元素和插入一个元素时执行效率就非常低,因为还要对剩下的元素进行移动

names = ['raymond', 'rachel', 'matthew', 'roger', 'betty', 'melissa', 'judith', 'charlie']

names.pop(0)
names.insert(0, 'mark')

pythonic

from collections import deque

names = deque(['raymond', 'rachel', 'matthew', 'roger','betty', 'melissa', 'judith', 'charlie'])

names.popleft()
names.appendleft('mark')

deque 是一个双向队列的数据结构,删除元素和插入元素会很快

9、序列解包

p = 'vttalk', 'female', 30, 'python@qq.com'

name = p[0]
gender = p[1]
age = p[2]
email = p[3]

pythonic

name, gender, age, email = p

10、遍历字典的 key 和 value

方法一速度没那么快,因为每次迭代的时候还要重新进行hash查找 key 对应的 value。

方法二遇到字典非常大的时候,会导致内存的消耗增加一倍以上

# 方法一
for k in d:print (k, '--->', d[k])

# 方法二
for k, v in d.items():    print (k, '--->', v)

pythonic

for k, v in d.iteritems():    print (k, '--->', v)

iteritems 返回迭代器对象,可节省更多的内存,不过在 python3 中没有该方法了,只有 items 方法,等值于 iteritems。

 

11、链式比较操作

age = 18if age > 18 and age < 60:    print("young man")

pythonic

if 18 < age < 60:    print("young man")

理解了链式比较操作,那么你应该知道为什么下面这行代码输出的结果是 False。

>>> False == False == True 
False

12、if/else 三目运算

if gender == 'male':text = '男'else:    text = '女'

pythonic

text = '男' if gender == 'male' else '女'

在类C的语言中都支持三目运算 b?x:y,Python之禅有这样一句话:

“There should be one-- and preferably only one --obvious way to do it. ”。

能够用 if/else 清晰表达逻辑时,就没必要再额外新增一种方式来实现。

13、真值判断

检查某个对象是否为真值时,还显示地与 True 和 False 做比较就显得多此一举,不专业

if attr == True:do_something()if len(values) != 0: # 判断列表是否为空do_something()

pythonic

if attr:do_something()if values:do_something()

真假值对照表:

   类型         FalseTrue
布尔False (与0等价)True (与1等价)
字符串""( 空字符串)非空字符串,例如 " ", "blog"
数值0, 0.0非0的数值,例如:1, 0.1, -1, 2
容器[], (),至少有一个元素的容器对象,例如:[0], (None,), ['']
NoneNone非None对象

 

14、for/else语句

for else 是 Python 中特有的语法格式,else 中的代码在 for 循环遍历完所有元素之后执行。

flagfound = False

for i in mylist:    if i == theflag:        flagfound = True        break    process(i)

if not flagfound:    raise ValueError("List argument missing terminal flag.")

pythonic

for i in mylist:if i == theflag:breakprocess(i)
else:raise ValueError("List argument missing terminal flag.")

15、字符串格式化

s1 = "foofish.net"
s2 = "vttalk"
s3 = "welcome to %s and following %s" % (s1, s2)

pythonic

s3 = "welcome to {blog} and following {wechat}".format(blog="foofish.net", wechat="vttalk")

很难说用 format 比用 %s 的代码量少,但是 format 更易于理解。

“Explicit is better than implicit --- Zen of Python”

16、列表切片

获取列表中的部分元素最先想到的就是用 for 循环根据条件提取元素,这也是其它语言中惯用的手段,而在 Python 中还有强大的切片功能。

items = range(10)

# 奇数
odd_items = []
for i in items:    if i % 2 != 0:        odd_items.append(i)

# 拷贝
copy_items = []
for i in items:    copy_items.append(i)

pythonic

# 第1到第4个元素的范围区间
sub_items = items[1:4]
# 奇数
odd_items = items[1::2]
#拷贝
copy_items = items[::] 或者 items[:]

列表元素的下标不仅可以用正数表示,还是用负数表示,最后一个元素的位置是 -1,从右往左,依次递减。

--------------------------| P | y | t | h | o | n |--------------------------   0   1   2   3   4   5  -6  -5  -4  -3  -2  -1--------------------------

17、善用生成器

def fib(n):a, b = 0, 1    result = []     while b < n:        result.append(b)        a, b = b, a+b    return result

pythonic

def fib(n):a, b = 0, 1    while a < n:        yield a        a, b = b, a + b

上面是用生成器生成费波那契数列。生成器的好处就是无需一次性把所有元素加载到内存,只有迭代获取元素时才返回该元素,而列表是预先一次性把全部元素加载到了内存。此外用 yield 代码看起来更清晰。

18、获取字典元素

d = {'name': 'foo'}

if d.has_key('name'):    print(d['name'])
else:    print('unkonw')

pythonic

d.get("name", "unknow")

19、预设字典默认值

通过 key 分组的时候,不得不每次检查 key 是否已经存在于字典中。

data = [('foo', 10), ('bar', 20), ('foo', 39), ('bar', 49)]
groups = {}

for (key, value) in data:    if key in groups:        groups[key].append(value)    else:        groups[key] = [value]

pythonic

# 第一种方式
groups = {}
for (key, value) in data:    groups.setdefault(key, []).append(value)

# 第二种方式
from collections import defaultdict
groups = defaultdict(list)

for (key, value) in data:    groups[key].append(value)

20、字典推导式

在python2.7之前,构建字典对象一般使用下面这种方式,可读性非常差

numbers = [1,2,3]
my_dict = dict([(number,number*2) for number in numbers])
print(my_dict)  # {1: 2, 2: 4, 3: 6}

pythonic

numbers = [1, 2, 3]
my_dict = {number: number * 2 for number in numbers}
print(my_dict)  # {1: 2, 2: 4, 3: 6}# 还可以指定过滤条件
my_dict = {number: number * 2 for number in numbers if number > 1}
print(my_dict)  # {2: 4, 3: 6}

字典推导式是python2.7新增的特性,可读性增强了很多,类似的还是列表推导式和集合推导式。

 

21、快速翻转字符串

a = 'I love Python.'
reverse_a = a[::-1]

转载于:https://www.cnblogs.com/gczr/p/7089587.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/468287.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

我是不建议随便跳槽的

突然的留言我的微信好友很多&#xff0c;经常也有一些同学给我留言一些问题&#xff0c;当然能回答的我肯定会回答了&#xff0c;但是如果是非常难的技术问题&#xff0c;我一般会说「我要请教一下身边的朋友」&#xff0c;我会非常刻意的去回避我技术很水的这个问题&#xff0…

ubuntu c++检测usb口事件变化_拆解报告:美式双USBA口充电插座

----- 充电头网拆解报告 第1441篇 -----最近充电头网拿到了一款美式插座&#xff0c;这款产品相比常规墙插插座&#xff0c;除了配有两个双脚AC插口外&#xff0c;还有两个USB-A接口&#xff0c;支持直接插上数据线即可为两台设备进行同时充电。其中两个USB-A口都支持最大5V4.8…

lol 细节知识

上下路小兵相遇时间&#xff1a;1:50s . 2:20s... 上下路小兵第一只死亡时间2&#xff1a;01s 中路小兵相遇时间&#xff1a;1:39s . 2:09s... 第一个红刷新时间1:39s 。瞎子刷红有人帮要15s。每5分钟刷一次。 第一个蓝开打时间2:30s 。瞎子刷玩要到2:44s。每5分钟刷一次。 刷完…

div不继承父类样式_Python编程思想(27):类的继承

-----------支持作者请转发本文-----------李宁老师已经在「极客起源」 微信公众号推出《Python编程思想》电子书&#xff0c;囊括了Python的核心技术&#xff0c;以及Python的主要函数库的使用方法。读者可以在「极客起源」 公众号中输入 160442 开始学习。-----------正文---…

mysql 举例_MySQL 语句举例(一)

举例&#xff1a;有10个用户&#xff0c;输出在订单表中下单数最多的5个人的名字。my_user 表数据my_order&#xff0c;uid对应my_user表的id测试数据生成写一个存储过程&#xff0c;随机插入10000条数据&#xff1a;CREATE DEFINERrootlocalhost PROCEDURE test_loop( )BEGIND…

你知道Linux里D进程会搞事吗?

前言这篇文章是一位大神在实际项目中遇到问题并分析总结出来的&#xff0c;作为新手&#xff0c;能接触到这类文章应该是受益匪浅&#xff0c;这位同学现在在魅族工作&#xff0c;以后也会一直在魅族工作&#xff0c;是Linux 方面的专家&#xff0c;「魅族还有另一个Linux 大神…

react-router 页面离开 提示数据变更

以前项目使用 react-router2.0&#xff0c; 业务层面页面离开的时候需要弹出自己的弹出框&#xff0c;根据用户的操作&#xff0c;进行是否可以离开 试了几种方式都存在问题&#xff0c;实现的并不完美&#xff0c;没办法对用户点击浏览器后退支持的很好&#xff0c;除非是显示…

java interface和impl_为什么要使用Interface,而不是直接使用一个实体类来完成任务?Interface和Impl这种方式的好处是什么?...

大家好&#xff0c;我是IT修真院北京分院的学员刘佳义&#xff0c;一枚正直善良的JAVA程序员。今天给大家分享一下&#xff0c;修真院官网任务中可能会使用到的知识点&#xff1a;为什么要使用Interface&#xff1f;Interface和Impl有什么好处1.背景介绍&#xff1a;首先咱们来…

python批量访问网页保存结果_Python检测批量URL状态,并将返回正常的URL保存文件...

-- coding: UTF-8 -- #author huangyishan import os import sys import urllib2 urls sys.argv[1] #从程序外部调用参数&#xff0c;0即程序本身 result list() def check_url_status(): f open(urls,‘r‘) #以读方式打开文件 for line in f.readlines(): #依次读取每行 …

caffe使用ctrl-c不能保存模型

caffe使用Ctrl-c 不能保存模型&#xff1a; 是因为使用的是 tee输出日志   解决方法&#xff1a;kill -s SIGINT <proc_id>   或者使用   GLOG_log_dir/path/to/log/dir $CAFFE_ROOT/bin/caffee.bin train     —solver/path/to/solver.prototxt  来输出日志…

C语言系列文章之#和##

很久就知道了 # 和 ## &#xff0c;但是都没怎么使用&#xff0c;直到最近的项目涉及到需要编写大量相似的代码之后才决定尝试使用 ## 去简化代码的书写。比如说我的项目需要控制四个通道的电机&#xff0c;四个通道的逻辑控制代码都是类似的&#xff0c;只是对应的硬件和数据信…

java ioc和aop的含义_Spring核心IoC和AOP的理解

spring 框架的优点是一个轻量级笔记简单易学的框架&#xff0c;实际使用中的有点优点有哪些呢&#xff01;1.降低了组件之间的耦合性 &#xff0c;实现了软件各层之间的解耦2.可以使用容易提供的众多服务&#xff0c;如事务管理&#xff0c;消息服务等3.容器提供单例模式支持4.…

springboot 上传文件_基于SpringBoot的文件上传

在实际的企业开发中&#xff0c;文件上传是最常见的功能之一&#xff0c;SpringBoot集成了SpringMVC常用的功能&#xff0c;当然也包含了文件上传的功能&#xff0c;实现起来没有太多的区别。下面我们来讲解一下&#xff0c;使用SpringBoot如何实现多个文件上传操作。使用的环境…

看雪KSSD-windows驱动

KanXue Software Security Documentation ,简称KSSD ,是一个在线的文档浏览查阅系统 1. 书籍推荐 《windows 2000 内部揭密>>--------------------------------------这里面可以学到什么是IRP、内存管理、文件系统之类 《驱动模型设计>>-------------------------…

Linux的 i2c 驱动框架分析

1.基本概念总线设备驱动模型&#xff0c;是Linux 内核的一个基础&#xff0c;基本理论可以说按照大企业的分工原则&#xff0c;每个人只要负责自己的事情&#xff0c;向其他部门给出标准的接口调用&#xff0c;后勤部就负责后勤工作&#xff0c;厨房有可能跟后勤部产生工作上的…

java ee程序设计师_软件设计师:Java EE开发四大常用框架[1]

StrutsStruts是一个基于Sun Java EE平台的MVC框架&#xff0c;主要是采用Servlet和JSP技术来实现的。Struts框架可分为以下四个主要部分&#xff0c;其中三个就和MVC模式紧密相关&#xff1a;1、模型 (Model)&#xff0c;本质上来说在Struts中Model是一个Action类(这个会在后面…

26、字符串的操作

字符串的操作 一、字符串的反向输出&#xff08;逆置&#xff09; /*2017年3月17日13:18:39功能&#xff1a;将字符串反向输出 */ #include"stdio.h" int main () {char a[100];char b[100];printf("please input one array: ");gets(a);char *pa a;char …

matlab fftshift_数字信号处理没有Matlab?用Python一样很爽

通常&#xff0c;在数字信号处理时&#xff0c;我们避不开matlab这个工具&#xff0c;因其它的强大的功能受到广大工程师的好评&#xff0c;也一直都是业界的不二之选。但是&#xff0c;matlab毕竟是商业软件&#xff0c;公司里如果使用的话&#xff0c;就需要支付高昂的费用。…

栈,C语言实现

什么是数据结构&#xff1f;数据结构是什么&#xff1f;要了解数据结构&#xff0c;我们要先明白数据和结构&#xff0c;数据就是一些int char 这样的变量&#xff0c;这些就是数据&#xff0c;如果你是一个篮球爱好者&#xff0c;那么你的球鞋就是你的数据&#xff0c;结构就是…