老齐教室

python绝技30例

Python绝技30例

作者:Erik-Jan van Baaren

翻译:老齐


如果你使用Python,下面要介绍的30个技巧,是能够让你提高编码效率的最佳方案,不得不看。

Life is short, You need Python.

1.使用Python3

从2020年1月1日起,Python2已经正式退役了。下面的所有说明,都仅适用于Python3。如果你还停留在Python2.7,现在就应该升级。MacOS系统中,使用Homebrew就能轻松升级Python。

2.检查程序所需的最低Python版本

你可以检查程序中的Python版本,以确保用户没有使用不兼容的版本运行。可以用下列代码进行简单检查:

1
2
3
4
5
6
if not sys.version_info > (2, 7):
# berate your user for running a 10 year
# python version
elif not sys.version_info >= (3, 5):
# Kindly tell your user (s)he needs to upgrade
# because you're using 3.5 features

3.使用IPython

IPython基本上是一个增强的shell,只看它的拼写自动填充功能,你就觉得用它是值得的。它的优点有很多,我很喜欢所有内置的魔法命令,在这里列举几个这样的命令:

  • %cd —— 更改当前工作目录
  • %edit —— 打开编辑器并在关闭编辑器后执行键入的代码
  • %env —— 显示当前环境变量
  • %pip install [pkgs] —— 在不离开交互式shell的情况下安装软件包
  • %time和%timeit —— 对Python代码的执行进行计时

另一个有用的特性是引用前面的输出,In和Out都是实际的对象,你可以借助Out[3]来使用第三个命令的输出。

安装IPython:

1
pip3 install ipython

4. 列表解析

列表解析可以替换丑陋的用于追加列表的for循环。列表解析的基本语法是:

1
[ expression for item in list if conditional ]

下面的示例演示了用数字填充列表的操作:

1
2
3
mylist = [i for i in range(10)] 
print(mylist)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

可以使用一个表达式,也可以做一些数学运算:

1
2
3
squares = [x**2 for x in range(10)]
print(squares)
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

甚至调用外部函数:

1
2
3
4
5
6
def some_function(a):
return (a + 5) / 2

my_formula = [some_function(i) for i in range(10)]
print(my_formula)
# [2, 3, 3, 4, 4, 5, 5, 6, 6, 7]

还可以在列表中使用if实现筛选操作,例如找出偶数:

1
2
3
filtered = [i for i in range(20) if i%2==0] 
print(filtered)
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

5.检查对象占用的内存

使用sys.getsizeof()可以检查对象的内存使用情况:

1
2
3
4
5
import sys 2

mylist = range(0, 10000)
print(sys.getsizeof(mylist))
#48

稍等,为什么这个大列表只有48字节?

这是因为range函数返回的类只表现为一个列表,range函数比使用实际的数字列表更节省内存。

你可以使用列表解析来创建一个包含相同范围数字的列表:

1
2
3
4
import sys 2
myreallist = [x for x in range(0, 10000)]
print(sys.getsizeof(myreallist))
# 87632

6. 返回多个值

Python中的函数可以返回多个值,不需要把它们组装成字典、列表或类,原理如下:

1
2
3
4
5
6
def get_user(id):
# fetch user from database
# ....
return name, birthdate

name, birthdate = get_user(4)

对于有限数量的返回值,这是可以的。但任何超过3个值的都应该放入指定的数据对象中。

7.使用数据类

自3.7版以来,Python提供了数据类(data class)。比起普通的类或其他的,如返回多个值或字典,数据类有几个优点:

  • 数据类需要的代码数量少
  • 借助__eq__能够实现数据类对象的比较
  • __repr__为调试时打印数据类提供了接口
  • 数据类需要有类型提示,减少了出现bug的可能性

下面是数据类示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from dataclasses import dataclass 2

@dataclass
class Card:
rank: str
suit: str

card = Card("Q", "hearts") 9

print(card == card)
# True

print(card.rank)
#'Q'

print(card)
Card(rank='Q', suit='hearts')

8.变量就地交换

一个可以节省几行代码的小技巧:

1
2
3
4
5
6
7
8
9
a=1
b=2
a, b = b, a

print (a)
#2

print (b)
#1

9.合并字典(Python3.5+)

自Python 3.5以来,合并字典变得更加容易:

1
2
3
4
5
dict1={'a':1,'b':2}
dict2={'b':3,'c':4}
merged = { **dict1, **dict2 }
print (merged)
# {'a': 1, 'b': 3, 'c': 4}

如果存在重复的键,第一个字典中的键值对将被覆盖。

10. 标题首字母大写

这只是字符串方法中的一个惬意之处:

1
2
3
mystring = "10 awesome python tricks" 
print(mystring.title())
# '10 Awesome Python Tricks'

11.将字符串拆分为列表

可以将字符串拆分为列表。在本例中,以空格为分隔符:

1
2
3
4
mystring = "The quick brown fox"
mylist = mystring.split(' ')
print(mylist)
# ['The', 'quick', 'brown', 'fox']

12. 将列表组合成字符串

与前面的操作相反,将列表中的元素组合为字符串,并在每个元素之间以空格为分隔符:

1
2
3
4
mylist = ['The', 'quick', 'brown', 'fox']
2 mystring = " ".join(mylist)
3 print(mystring)
4 # 'The quick brown fox'

如果你想问为什么不是mylist.join(" ")——好问题!

归根结底,String.join()函数不仅可以连接列表,还可以连接任何可迭代对象。把它放在字符串中可以防止在多个地方实现相同的功能。

13. 表情符号

这些表情符号,要么给人留下深刻印象,要么让人反感,这取决于谁在看。更重要的是,在分析社交媒体数据时,它可以派上用场。

首先,安装EMOJI模块:

1
pip3 install emoji

安装完毕,你可以做以下事情:

访问emoji的官方网站,可以看到更多示例。

14. 列表切片

列表切片的基本语法是:

1
a[start:stop:step]

Start,表示开始的索引;stop,表示结束位置的索引;ste,表示步长。start的默认值是0,step的默认值是1.

下面是一些例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 创建一个列表,获取其前两个元素。
first_two = [1, 2, 3, 4, 5][0:2]
print(first_two)
# [1, 2]

# 将步长设置为2,即隔一个取一个元素:
steps = [1, 2, 3, 4, 5][0:5:2]
print(steps)
# [1, 3, 5]

# 字符串也可以做同样的切片。
mystring = "abcdefdn nimt"[::2]
print(mystring)
# 'aced it'

15. 反转字符串和列表

你可以使用上面的切片来反转字符串或列表,将步长值设置为-1,可以反转元素:

1
2
3
4
5
6
7
revstring = "abcdefg"[::-1]
print(revstring)
# 'gfedcba'

revarray = [1, 2, 3, 4, 5][::-1]
print(revarray)
# [5, 4, 3, 2, 1]

16. 读取图片

用Python读取图片,首先,安装Pillow,这是Python中的一个图像库:

1
pip3 install Pillow

现在将这个图像下载到本地,命名为kittens.jpg:

用下面的Python代码读此图片文件:

1
2
3
4
5
from PIL import Image 2
im = Image.open("kittens.jpg")
im.show()
print(im.format, im.size, im.mode)
6 # JPEG (1920, 1357) RGB

Pillow不仅仅可以显示图像,它可以对图像进行分析、调整大小、过滤、变形等。有关其所有功能,请参阅文档。

17.使用map()

map()是Python的一个内置函数,它的语法是:

1
map(function, something_iterable)

所以你给它一个要执行的函数和一些要执行的东西,可以是任何可迭代的东西。在下面的示例中,我将使用一个列表。

1
2
3
4
5
6
7
8
9
10
11
12
def upper(s):
return s.upper()

mylist = list(map(upper, ['sentence', 'fragment']))
print(mylist)
# ['SENTENCE', 'FRAGMENT']

# Convert a string representation of
# a number into a list of ints.
list_of_ints = list(map(int, "1234567")))
print(list_of_ints)
# [1, 2, 3, 4, 5, 6, 7]

看看你自己的代码,是否可以使用map()而不是某个循环!

18.从列表或字符串中获取唯一元素

使用set()函数创建集合,你可以从列表或类似列表的对象中获取所有的唯一元素:

1
2
3
4
5
6
7
8
9
mylist=[1,1,2,3,4,5,5,5,6,6]
print (set(mylist))
# {1, 2, 3, 4, 5, 6}

# And since a string can be treated like a
# list of letters, you can also get the
# unique letters from a string this way:
print (set("aaabbbcccdddeeefff"))
# {'a', 'b', 'c', 'd', 'e', 'f'}

19. 找出高频值

要在列表或字符串中查找最常出现的值,请执行以下操作:

1
2
3
test=[1,2,3,4,2,2,3,1,4,4,4] 
print(max(set(test), key = test.count))
#4

你明白为什么这样能奏效吗?在阅读下文之前,试着自己弄清楚。

你没试过吧?不管怎样,我都会告诉你:

  • max()将返回列表中的最大值。key参数的值是一个函数,它定义了排序规则,在本例中为test.count,该函数应用于可迭代对象的每个项。
  • test.count是列表的方法,它接受一个参数并计算该参数的出现次数。所以test.count(1)将返回2,test.count(4)返回4。
  • set(test)返回test中的所有唯一值,因此得到{1、2、3、4}

所以我们在这一行代码中要做的是获取test的所有唯一值,即{1,2,3,4}。接下来,max将把list.count函数应用于它们并返回最大值。

诚然,这行代码不是我发明的。

20.创建进度条

你可以创建自己的进度条,这很有趣。推荐使用下面的第三方包:

1
pip3 install progress

现在,你可以轻松创建进度条:

1
2
3
4
5
6
7
from progress.bar import Bar

bar = Bar('Processing', max=20)
for i in range(20):
# Do some work
bar.next()
bar.finish()

在运行过程中,会有动画效果。

21. 在IPython中使用下划线

你可以使用下划线获得最后一个表达式的结果,在IPython,它看起来是这样的:

1
2
3
4
In [1]: 3 * 3 
Out[1]: 9
In [2]: _ + 3
Out[2]: 12

这也适用于Python shell。此外,IPython shell允许使用Out[n]来获取表达式In[n]的值。例如,在上面的例子中,Out[1]会输出数字9。

22.快速创建web服务器

你可以快速启动web服务器,以便将当前目录的内容发出去:

1
python3 -m http.server

如果你想和同事分享一些东西,或者想测试一个简单的HTML站点,这很有用。

23.多行字符串

尽管可以使用三重引号在代码中包含多行字符串,但这并不理想。在三个引号之间放置的所有内容都将成为字符串,包括格式,如下所示。

我更喜欢第二种方式,它将多行连接在一起,允许你把代码漂亮地格式化。唯一的缺点是需要显式地添加换行符。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
s1 = """Multi line strings can be put
between triple quotes. It's not ideal
when formatting your code though"""

print(s1)
# Multi line strings can be put
# between triple quotes. It's not ideal
# when formatting your code though

s2 = ("You can also concatenate multiple\n" +
"strings this way, but you'll have to\n"
"explicitly put in the newlines")

print(s2)
# You can also concatenate multiple
# strings this way, but you'll have to
# explicitly put in the newlines

24. 条件语句的三元操作

这是另一种方法,它使你的代码更简洁,同时保持可读性:

1
[on_true] if [expression] else [on_false]

例如:

1
x = "Success!" if (y == 2) else "Failed!"

25.计数

您可以使用collections中的Counter对列表中的元素进行计数,得到的是类字典对象,其中记录了每个元素的数量:

1
2
3
4
5
6
7
8
9
10
from collections import Counter

mylist=[1,1,2,3,4,5,5,5,6,6]
c = Counter(mylist)
print(c)
# Counter({1: 2, 2: 1, 3: 1, 4: 1, 5: 3, 6: 2})

# And it works on strings too:
print(Counter("aaaaabbbbbccccc"))
# Counter({'a': 5, 'b': 5, 'c': 5})

26. 链式比较

你可以在Python中链接比较运算符,从而创建更具可读性和更简洁的代码:

1
2
3
4
5
6
7
8
9
10
11
x=10 

# Instead of:
if x > 5 and x < 15:
print("Yes")
#yes

# You can also write:
if 5 < x < 15:
print("Yes")
#Yes

27. 着色

使用Colorama,你可以让终端添加色彩绚丽。

1
2
3
4
5
6
from colorama import Fore, Back, Style 2
print(Fore.RED + 'some red text')
print(Back.GREEN + 'and with a green background')
print(Style.DIM + 'and in dim text')
print(Style.RESET_ALL)
print('back to normal now')

28.使用日期

python-dateutil模块为标准datetime模块提供了强大的扩展。安装方式:

1
pip3 install python-dateutil

你可以用这个库做很多很酷的事情。我只举一个我觉得特别有用的例子:对日志文件中的日期进行模糊解析等等。

1
2
3
4
5
6
from dateutil.parser import parse

logline = 'INFO 2020-01-01T00:00:01 Happy new year, human.'
timestamp = parse(log_line, fuzzy=True)
print(timestamp)
# 2020-01-01 00:00:01

只需记住:当常规Python中的datetime鞭长莫及时,就是python-dateutil大显身手的时候!

29.整数除法

在Python 2中,除法运算符(/)默认为整数除法(即商是整数),除非其中一个操作数是浮点数。所以:

1
2
3
# Python 2 
5 / 2 = 2
5 / 2.0 = 2.5

在Python 3中,除法运算符默认为浮点除法(即商是浮点数),//已成为整数除法运算符。所以:

1
2
3
#Python 3 
5 / 2 = 2.5
5 // 2 = 2

要了解这一变化背后的全部动机,你应该阅读PEP-0238。

30.使用chardet检测字符集

可以使用chardet模块检测文件的字符集,这在分析大量随机文本时非常有用。安装方式:

1
pip install chardet

现在,可以使用chardetect命令,使用方法如下:

1
2
chardetect somefile.txt 
somefile.txt: ascii with confidence 1.0

你也可以通过编程的方式使用这个库,详情请查阅文档。

就是这样!新的一年开始的30种秘诀。我希望你和我一样喜欢这份清单,如果你有什么要补充的,请在微信公众号中回复留言!

原文链接:https://towardsdatascience.com/30-python-best-practices-tips-and-tricks-caefb9f8c5f5

关注微信公众号:老齐教室。读深度文章,得精湛技艺,享绚丽人生。

使用支付宝打赏
使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

关注微信公众号,读文章、听课程,提升技能