python代码技巧_编写优质python代码的10个技巧

编写优质python代码的10个技巧

1. 用enumerate代替range(len())

如果在遍历列表时,同时获得索引和数据,你可以使用range(len()) 这种语法

lst = [87, 84, 34]

for index in range(len(lst)):

print(index, lst[index])

这种写法虽然可以实现同时遍历索引和元素,但编写过程并不流畅,如果使用enumerate就可以避免使用索引来获取元素

lst = [87, 84, 34]

for index, item in enumerate(lst):

print(index, item)

实现相同的功能,使用enumerate让代码看起来更加的清爽。

2. 使用列表推导式代替for循环

创建一个列表,列表里的元素是从0到9的整数序列,使用for循环,你可以这样编写

lst = []

for i in range(10):

lst.append(i)

print(lst)

使用列表推导式,可以写出更加简洁的代码,不仅如此,列表推导式的性能更快

lst = [i for i in range(10)]

print(lst)

3. 使用sorted函数对序列进行排序

列表支持sort方法,可以对列表里的元素进行排序,而sorted函数更加强大,它对序列排序后,返回一个新的列表

lst = [5, 1, 3]

lst.sort() # 对列表排序

print(lst)

tup = (5, 1, 3) # 元组不支持sort方法

sort_lst = sorted(tup, reverse=True)

print(sort_lst)

同列表的sort方法一样,sorted也支持key参数来指定排序比较大小时的数值

lst = [(3, 5), (6, 2), (1, 6)]

lst.sort(key=lambda x: x[0]) # 对列表排序

print(lst)

tup = ((3, 5), (6, 2), (1, 6)) # 元组不支持sort方法

sort_lst = sorted(tup,key=lambda x: x[0], reverse=True)

print(sort_lst)

如果需要被排序的序列不是列表,或者你不希望需改原有的列表,那么你应当选择sorted函数进行排序

4. 使用生成器节省内存

如果你需要产生一个比较大的序列,那么强烈建议你使用生成器而非列表。列表会占用非常大的内存,而生成器不会。

import sys

lst1 = [i for i in range(10000) if i %2 == 0] # 偶数序列

lst2 = [i for i in range(10000) if i %2 != 0] # 奇数序列

lst = [(i, j) for i, j in zip(lst1, lst2)]

print(sys.getsizeof(lst1) + sys.getsizeof(lst2) + sys.getsizeof(lst), 'bytes')

lst1 = (i for i in range(10000) if i %2 == 0)

lst2 = (i for i in range(10000) if i %2 != 0)

lst = ((i, j) for i, j in zip(lst1, lst2))

print(sys.getsizeof(lst1) + sys.getsizeof(lst2) + sys.getsizeof(lst), 'bytes')

两种写法所使用的内存量相差非常大

129120 bytes

264 bytes

生成器是延迟计算,你只能对其使用for循环遍历,而不能像对待列表一样使用切片方法,因为事先并不存在一个完整的序列,只有在for循环进行时,才会产生相应的数据。

5. 使用get方法和setdefault方法获取和设置字典的value

在使用字典进行统计时,强烈建议你使用setdefault方法设置一个key的初始值,现在,请使用字典统计列表里各个单词出现的次数,如果不使用setdefault,你必须这样来写代码

lst = ['python', 'python', 'java', 'c++', 'java', 'php']

word_count_dict = {}

for word in lst:

# 如果key不存在则设置初始值

if word not in word_count_dict:

word_count_dict[word] = 0

word_count_dict[word] += 1

这样实现,到也并非是个坏方法,但对word进行一次是否是字典key的判断,还是有些多余,如果使用setdefault方法,则可以避免

lst = ['python', 'python', 'java', 'c++', 'java', 'php']

word_count_dict = {}

for word in lst:

word_count_dict.setdefault(word, 0)

word_count_dict[word] += 1

少了一行if条件语句,让代码看起来更加简洁了,如果word已经是字典的key,那么setdefault方法不会起到任何作用,不会改变key对应的value,但如果key不存在,则会设置key对应的value为0。

在从字典里通过key取值时,如果key不存在,则会引发KeyError 异常,如果不会异常进行捕获,就会导致程序崩溃。对于这种情况,建议你使用get方法,它是一种安全的方法,如果key在字典里不存在,则返回默认值None,你也可以设置key不存在时返回的默认值。

print(word_count_dict.get('node.js')) # 返回None

print(word_count_dict.get('node.js', 3)) # 返回3

6. 使用collections.Counter对列表进行统计

第5小结的示例,讲解了如何用字典统计列表里单词的出现次数,对于这类操作,使用collections.Counter更加方便,collections模块提供了非常多有用的类

from collections import Counter

lst = ['python', 'python', 'java', 'c++', 'java', 'php']

counter = Counter(lst)

print(counter) # Counter({'python': 2, 'java': 2, 'c++': 1, 'php': 1})

print(counter['python']) # 2

Counter提供了most_common方法,可以返回出现次数最多的元素

most_common = counter.most_common(2)

print(most_common) # [('python', 2), ('java', 2)]

7. 使用 f-Strings 格式化字符串

从3.6 版本后,就不要在使用% 和 format方法对字符串进行格式化了,因为f-Strings提供了更加方便快捷的格式化方法,下面的代码,将对比这三种格式化的操作

name = '小明'

age = 14

msg = "%s今年%d岁" % (name, age)

print(msg)

msg = "{name}今年{age}岁".format(name=name, age=age)

print(msg)

msg = f"{name}今年{age}岁"

print(msg)

孰优孰劣,诸位自行判断吧

8. 使用jion方法连接字符串

假如需要将列表里的单词连接成一个新的字符串, 你可以遍历列表,拼接字符串

lst = ['I', 'like', 'python']

my_string = ""

for word in lst:

my_string += word + " "

my_string = my_string[:-1] # 去掉最后一个空格

print(my_string)

这样拼接,不仅代码臃肿,由于每次都要在接入的单词后面加一个空格,导致整个句子最后也会有一个空格,不得不进行一次切片操作。每一次for循环,都会在内存中创建一个新的字符串,申请一片新的内存空间用以存储拼接后的字符串,如果数据量很大,这样的操作费时又费力。

如果使用join方法,则便捷的多

lst = ['I', 'like', 'python']

my_string = " ".join(lst)

print(my_string)

9. 使用解包操作简化代码

合并两个字典,可以使用下面的方法

dict_1 = {'python': 90}

dict_2 = {'java': 98}

dict_3 = {**dict_1, **dict_2} # {'python': 90, 'java': 98}

print(dict_3)

解包的用处不仅于此,还可以用它来快速的传递函数参数

def test(name='', age=0):

print(name, age)

info = {

'name': '小明',

'age': 18

}

test(**info)

10 . 使用三元表达式

python中是没有三元表达式的,但可以通过if ... else 伪装成三元表达式

lst = [2, 5, 6, 7]

bool_lst = []

for index, item in enumerate(lst):

if item % 2 == 0:

bool_lst[index] = True

else:

bool_lst[index] = False

创建一个bool_lst, 如果lst[i]是偶数,则bool_lst[i] 设置为True,反之设置为False, 上面的代码从逻辑上,没有任何问题,但使用伪三元表达式,可以简化代码编写

lst = [2, 5, 6, 7]

bool_lst = []

for index, item in enumerate(lst):

bool_lst[index] = True if item % 2 == 0 else False

想要写出简洁的代码,要对python的高级语法融会贯通,下面是另外两种写法

预先创建等长列表

lst = [2, 5, 6, 7]

bool_lst = [False for item in lst]

for index, item in enumerate(lst):

if item % 2 == 0:

bool_lst[index] = True

使用列表推导式

lst = [2, 5, 6, 7]

bool_lst = [True if item % 2 == 0 else False for item in lst ]

列表推导式虽然让代码更简洁,但要防止走向极端,如果推导式本身很复杂,甚至融入了业务逻辑,那么还是应该拆分成多行语句,尽管代码变多了,但易于理解和阅读。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值