首页 存档 技术 查看内容

教程 | 如何编写高效且优雅的 Python 代码(1)

2018-3-30 13:00 |来自: 互联网 368 0

摘要: Python 作为一门入门极易并容易上瘾的语音,相信已经成为了很多人 “写着玩” 的标配脚本语言。但很多教材并没有教授 Python 的进阶和优化。本文作为进阶系列的文章,从基础的语法到函数、迭代器、类,还有之后系列 ...

Python 作为一门入门极易并容易上瘾的语音,相信已经成为了很多人 “写着玩” 的标配脚本语言。但很多教材并没有教授 Python 的进阶和优化。本文作为进阶系列的文章,从基础的语法到函数、迭代器、类,还有之后系列的线程 / 进程、第三方库、网络编程等内容,共同学习如何写出更加 Pythonic 的代码


Pythonic


列表切割


list[start:end:step]

  • 如果从列表开头开始切割,那么忽略 start 位的 0,例如list[:4]

  • 如果从列表开头开始切割,那么忽略 start 位的 0,例如list[:4]

  • 如果一直切到列表尾部,则忽略 end 位的 0,例如list[3:]

  • 切割列表时,即便 start 或者 end 索引跨界也不会有问题

  • 列表切片不会改变原列表。索引都留空时,会生成一份原列表的拷贝

b = a[:]
assert b == a and b is not a # true


列表推导式

  • 使用列表推导式来取代mapfilter

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# use map
squares = map(lambda x: x ** 2, a)
# use list comprehension
squares = [x ** 2 for x in a]
# 一个很大的好处是,列表推导式可以对值进行判断,比如
squares = [x ** 2 for x in a if x % 2 == 0]
# 而如果这种情况要用 map 或者 filter 方法实现的话,则要多写
一些函数


  • 不要使用含有两个以上表达式的列表推导式

# 有一个嵌套的列表,现在要把它里面的所有元素扁平化输出

list = [[
[1, 2, 3],
[4, 5, 6]
]]
# 使用列表推导式
flat_list = [x for list0 in list for list1 in list0 for x in list1]
# [1, 2, 3, 4, 5, 6]

# 可读性太差,易出错。这种时候更建议使用普通的循环
flat_list = []
for list0 in list:
for list1 in list0:
flat_list.extend(list1)
  • 数据多时,列表推导式可能会消耗大量内存,此时建议使用生成器表达式

# 在列表推导式的推导过程中,对于输入序列的每个值来说,都可能要创建仅含一项元素的全新列表。因此数据量大时很耗性能。
# 使用生成器表达式
list = (x ** 2 for x in range(0, 1000000000))
# 生成器表达式返回的迭代器,只有在每次调用时才生成值,从而避免了内存占用



迭代

  • 需要获取 index 时使用enumerate

  • enumerate可以接受第二个参数,作为迭代时加在index上的数值

list = ['a', 'b', 'c', 'd']

for index, value in enumerate(list):
print(index)
# 0
# 1
# 2
# 3

for index, value in enumerate(list, 2):
print(index)
# 2
# 3
# 4
# 5


  • zip同时遍历两个迭代器

  list_a = ['a', 'b', 'c', 'd']
list_b = [1, 2, 3]
# 虽然列表长度不一样,但只要有一个列表耗尽,则迭代就会停止
for letter, number in zip(list_a, list_b):
print(letter, number)
# a 1
# b 2
# c 3


  • zip遍历时返回一个元组

  a = [1, 2, 3]
b = ['w', 'x', 'y', 'z']
for i in zip(a,b):
print(i)

# (1, 'w')
# (2, 'x')
# (3, 'y')


  • 关于for和while循环后的else

    • 循环正常结束之后会调用else内的代码

    • 循环里通过break跳出循环,则不会执行else

    • 要遍历的序列为空时,立即执行else


反向迭代


对于普通的序列(列表),我们可以通过内置的reversed( )函数进行反向迭代:

list_example = [i for i in range(5)]
iter_example = (i for i in range(5)) # 迭代器
set_example = {i for i in range(5)} # 集合

# 普通的正向迭代
# for i in list_example

# 通过 reversed 进行反向迭代
for i in reversed(list_example):
print(i)
# 4
# 3
# 2
# 1
# 0

# 但无法作用于 集合 和 迭代器
reversed(iter_example)
# TypeError: argument to reversed() must be a sequence


除此以外,还可以通过实现类里的__reversed__方法,将类进行反向迭代:

class Countdown:
def __init__(self, start):
self.start = start

# 正向迭代
def __iter__(self):
n = self.start
while n
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

相关分类

返回顶部