18

这 5 个 Python 特性,后悔没早知道

 4 years ago
source link: https://www.infoq.cn/article/DzbdLevAqB4etWb41mCX
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

r2uYVzM.jpg!web

作为近 10 年才崛起的编程语言,Python 已被证明是一种非常强大的语言。从 交互式映射区块链 ,我用 Python 构建过很多应用程序。

对初学者而言,Python 中有很多特性很难一开始就掌握。

即使你是从其他语言转换过来的程序员,用 Python 进行更高级别的抽象编码绝对是另一种体验。有些 Python 特性,我希望自己能早点知道。本文将介绍其 5 个最重要的特性。

1. 列表推导式:代码更紧凑

很多人认为, lambda、mapfilter 是初学者应该最先掌握的 Python“技巧”。虽然我也认为应关注这些功能,但由于它们缺乏灵活性。

实际上,它们在大多数情况下并不是非常有用!

Lambda 是一种在 1 行中编写一个一次性使用的函数的方法。一旦函数被多次调用,性能将受到影响。

另一方面, map 可以将一个函数应用于列表中的所有元素,而 filter 能获取集合中满足用户自定义条件的元素子集。

复制代码

add_func = lambda z: z **2
is_odd = lambda z: z%2==1
multiply = lambda x,y: x*y

aList = list(range(10))
print(aList)
# [0,1,2,3,4,5,6,7,8,9]

列表推导式是一个简洁而灵活的方法,它使用灵活的表达式和条件通过其他列表来创建新列表。

它用方括号来构造,带有一个表达式或函数,只有当列表中的元素满足某个条件时,该表达式或函数才作用于列表中的每个元素。

并且,它还能用嵌套来处理嵌套列表,并且这会比使用 map 和 filter 更灵活。

复制代码

# Syntax oflistcomprehension
[ expression(x) forxinaListifoptional_condition(x) ]

复制代码

print(list(map(add_func, aList)))
print([x **2for x in aList])
# [0,1,4,9,16,25,36,49,64,81]
# [0,1,4,9,16,25,36,49,64,81]

print(list(filter(is_odd, aList)))
print([x for x in aList if x%2==1])
# [1,3,5,7,9]
# [1,3,5,7,9]

下载地址: python-list-comprehension.py

2、列表操作:实现列表的双向操作

Python 允许使用反向索引,其中 aList[-1] == aList[len(aList)-1] 。所以,我们可以通过调用 aList[-2] 来获取列表的倒数第二个元素。

我们还能使用 aList[start:end:step] 语法来对列表进行切片,其中起始元素包含在内,终止元素不包含在内(即 [start,end) 步长为 step 的前闭后开区间)。

因此,调用 aList[2:5] 会得到 [2, 3, 4] 。我们也能通过调用 aList[::-1] 来反转列表,这种技术非常优雅。

此外,也可以将列表 拆分 成单独的元素,或者使用星号将列表拆分成单个元素和子列表的混合形式。

复制代码

a, b, c, d = aList[0:4]
print(f'a = {a}, b = {b}, c = {c}, d = {d}')
# a =0, b =1, c =2, d =3

a, *b, c, d = aList
print(f'a = {a}, b = {b}, c = {c}, d = {d}')
# a =0, b = [1,2,3,4,5,6,7], c =8, d =9

下载地址: python-unpacking.py

3、 压缩和枚举:for 循环更方便

Zip 函数会创建一个 迭代器 ,且该迭代器可以对来自多个列表的元素进行聚合。用它可以在 for 循环中对列表进行并行遍历和排序。

用星号对其进行解压。

复制代码

numList = [0,1,2]
engList = ['zero','one','two']
espList = ['cero','uno','dos']
print(list(zip(numList, engList, espList)))
# [(0,'zero','cero'), (1,'one','uno'), (2,'two','dos')]

for num, eng, esp in zip(numList, engList, espList):
print(f'{num} is {eng} in English and {esp} in Spanish.')
#0is zero inEnglishand cero inSpanish.
#1is one inEnglishand uno inSpanish.
#2is two inEnglishand dos inSpanish.

下载地址: python-zip-1.py

复制代码

Eng =list(zip(engList, espList,numList))
Eng.sort() #sortbyengList
a, b, c =zip(*Eng)

print(a)
print(b)
print(c)
# ('one', 'two', 'zero')
# ('uno', 'dos', 'cero')
# (1, 2, 0)

下载地址: python-zip-2.py

开始时, Enumerate 看起来有点吓人,但在很多情况下使用它确实能方便很多。

它是一个自动计数器,通常会在 for 循环中使用它,这样就不需要再用 counter = 0counter += 1 来创建和初始化计数器了。枚举和压缩是两个构造 for 循环的最强工具。

复制代码

upperCase = ['A','B','C','D','E','F']
lowerCase = ['a','b','c','d','e','f']
fori, (upper, lower)inenumerate(zip(upperCase, lowerCase),1):
print(f'{i}:{upper}and{lower}.')
# 1: A and a.
# 2: B and b.
# 3: C and c.
# 4: D and d.
# 5: E and e.
# 6: F and f.

下载地址: python-enumerate.py

4、生成器:内存更高效

当我们想要对一个大的结果集进行计算,但 又不想为所有结果数据同时分配内存时 ,我们就可以使用 生成器(Generator) 了。

换句话说,它会 动态地 生成值,并且不会将先前的值存储在内存中,因此我们只能对它们进行一次迭代操作。

当读取大文件或使用关键字 yield 生成无穷数列时,通常会用它。我发现在我的大多数数据科学项目中,它都能发挥很大作用。

复制代码

defgen(n):# an infinite sequence generator that generates integers >= n
whileTrue:
yieldn
n +=1

G = gen(3)# starts at 3
print(next(G))# 3
print(next(G))# 4
print(next(G))# 5
print(next(G))# 6

下载地址: python-generator.py

5、虚拟环境:实现隔离

如果在本文介绍的 5 个特性中只选一个,那么就是 虚拟环境 的使用。

Python 应用程序通常会用各种不同的包,这些包可能是由具有复杂依赖关系的不同开发人员开发的。每个应用程序都会用特定的库设置,使用其他库的版本无法实现对某个应用程序安装包的复制。

所以,不存在满足所有应用要求的单个安装包。

复制代码

conda create -n venv pippython=3.7#selectpythonversion
sourceactivate venv
...
sourcedeactivate

为每个应用程序创建独立的、自洽的虚拟环境 venv 非常重要,这可以通过使用 pipconda 来实现。

原文链接:

https://towardsdatascience.com/5-python-features-i-wish-i-had-known-earlier-bc16e4a13bf4


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK