编写优雅代码的7个不太为人所知的Python技巧

编写优雅代码的7个不太为人所知的Python技巧总的来说,这是一个很好的学习经历

总的来说,这是一个很好的学习经历。我不仅从组织者那里学到了大量的技巧,而且还从其他训练营学员那里学到了大量的技巧。大家都强调要最大限度地利用Python的内置函数和模块,以及编写干净和优雅的代码。

这篇文章既是我记录这些我学到的新技巧的方式,也是我与你分享它们的努力。它们帮助我大大提高了Python编程技能,我希望它们也能以同样的方式帮助你。你准备好了吗?让我们直接进入!

目录

  1. 被低估的enumerate()
  2. int() 函数比你想象的更有用
  3. 让我们断言:assert语句!
  4. 解压和打包–*操作符的力量
  5. 从字典中检索值?使用.get() 并抛弃[]!
  6. defaultdict – 用默认值创建字典
  7. 用任何你想要的方式排序sorted

1.被低估的enumerate()

循环遍历可迭代对象,如列表、图元或字符串,是非常常见的。我们中的一些人可能会做这样的事情。

>>> lst = ["a", "b", "c", "d"]>>> for idx in range(len(lst)):...     print(f"Index: {idx} --> Element: {lst[idx]}")

如果我们只是简单地通过列表,那么计算其长度范围是多余的。相反,我们可以使用enumerate() ,它是一个内置的函数,就是为了这样一个目的。enumerate() 函数返回一个枚举对象,它持有一个可迭代对象的索引和元素对。

>>> enumerate(lst)<enumerate at 0x1dde1211e80>

如果你把它包在list() ,你可以看到这些对。

>>> list(enumerate(lst))[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]

使用enumerate() ,先前的代码可以重写为。

>>> lst = ["a", "b", "c", "d"]>>> for idx, item in enumerate(lst):...     print(f"Index: {idx} --> Element: {item}")

假设你希望起始索引是1,而不是0。你可以用可选的start 参数来指定。

>>> lst = ["a", "b", "c", "d"]>>> for idx, item in enumerate(lst, start=1):...     print(f"Index: {idx} --> Element: {item}")

2.int()函数比你想象的更有用

你可能使用过int(),将一个字符串或一个浮点数转换成一个整数。

# Converting a string into an integer>>> var = "5">>> print(int(var))>>> print(type(int(var)))

对于一个字符串来说,它必须是一个有效的整数的字符串表示,否则会引发错误。

# Converting a string into an integer>>> var = "5.4321">>> print(int(var))>>> print(type(int(var)))

有趣的是,当把一个字符串表示的整数转换为整数时,int() 函数允许存在空白处。

>>> int("5\n") == int("   5  ") == int("\t\n 5 \n\t ") == 5

对于浮点数,int()函数会将小数点截去。

# Converting a float into an integer>>> var = 5.4321>>> print(int(var))>>> print(type(int(var)))

除了字符串和浮点数,你知道吗,int()也可以用来将二进制数字解析为整数?我们只需要指定base=2 参数。

# Converting binary numbers into an integer>>> print(int("1000", base=2))>>> print(int("111110100", base=2))

3.让我们来断言那个断言语句!

assert 语句是一个布尔表达式,检查一个条件是否为真。条件在assert 关键字之后。如果条件为真,什么都不会发生,程序将进入下一行代码。

>>> x = "Hello, World!">>> assert x == "Hello, World!">>> print(x)

然而,如果条件为假,代码就会停止,并触发一个错误。

>>> x = "Hello, World!">>> assert x == "Hi, World!">>> print(x)

你还可以在条件后面指定一个自定义的错误信息。

>>> x = "Hello, World!">>> assert x == "Hi, World!", "Uh oh, the condition is not met!">>> print(x)

所以,一般的语法是这样的。

assert <insert condition>, <insert optional error message>

因为只要不满足条件,程序就会停止,所以assert语句是一个很好的调试工具–可以看到你的代码的哪些部分失败了,为什么?例如,你可以用它来检查数据类型或进入函数的特定输入值,或者在给定某些固定输入的情况下,检查函数的输出值。

4.解压和打包–*运算符的力量

解压和打包是Python中有用且方便的功能。你可以将存储在迭代器中的值解压,如赋值运算符右边的图元、字符串和列表,并将它们赋给赋值运算符左边的变量。这些变量将根据它们在迭代表中的相对位置被赋值。

# Unpacking a tuple>>> a, b, c = (1, 2, 3)>>> print(a)>>> print(b)>>> print(c)

另一方面,打包使用* 操作符,它允许你在一个变量中打包多个值。

# Packing with a tuple>>> a, *b = (1, 2, 3)>>> print(a)>>> print(b)

除了图元、列表和字符串,打包和解包也可以适用于生成器对象、集合和字典。当你想在变量之间交换数值或同时进行多个赋值时,这是一个很方便的工具。它使你的代码更有可读性。

# Swapping values between variables>>> a = 1>>> b = 2>>> a, b = b, a>>> print(a)>>> print(b)

如果你有兴趣了解更多,这里有一篇关于打包和解包的文章,解释得很清楚。

5.从字典中检索值?使用 .get() 和 ditch []!

假设你有一个字典,它将一个键映射到它相应的值。在下面的例子中,为了检索num_to_words 字典中一个键的英文单词,你可能想使用方括号。

>>> num_to_words = {1: 'one', 2: 'two', 3: 'three'}>>> print(num_to_words[2])

如果你想检索num_to_words 词典中不存在的键的英文单词,该怎么办?是的,你猜对了–它引发了一个错误!

>>> num_to_words = {1: 'one', 2: 'two', 3: 'three'}>>> print(num_to_words[4])

与方括号相比,.get() 方法将是一个更稳健和实用的选择。.get() 方法返回字典中存在的键的值,与使用方括号没有区别。

>>> num_to_words = {1: 'one', 2: 'two', 3: 'three'}>>> print(num_to_words.get(2))

现在,当查询字典中一个不存在的键的值时,.get() 的好处就明显了。它不会触发KeyError 并破坏你的代码,而是默认返回一个值None 并保持你的代码运行。

>>> num_to_words = {1: 'one', 2: 'two', 3: 'three'}>>> print(num_to_words.get(4))

.get() 的好处是,你甚至可以指定一个自定义的值,在找不到键的时候返回。

>>> num_to_words = {1: 'one', 2: 'two', 3: 'three'}>>> print(num_to_words.get(4, "Uh oh... key is not found!"))

.get() 的一个用例是在用字典中的相应值替换列表中的值时非常有用。在下面的例子中,我们想用num_to_words 字典将num_list 中的每个元素替换成其相应的英文单词。如果使用方括号,代码就会中断,因为4 不在字典的键中。

# Using square brackets>>> num_to_words = {1: 'one', 2: 'two', 3: 'three'}>>> num_list = [1, 2, 3, 4, 5, 6]>>> word_list = [num_to_words[num] for num in num_list]>>> print(word_list)

然而,如果我们使用.get() 方法来代替,代码就可以工作。

# Using .get() method with default value of None>>> num_to_words = {1: 'one', 2: 'two', 3: 'three'}>>> num_list = [1, 2, 3, 4, 5, 6]>>> word_list = [num_to_words.get(num) for num in num_list]>>> print(word_list)

也许,.get() 对不存在的键返回None ,还是不理想。我们可以指定.get() 方法的第二个参数,这样它就会返回键本身,如果它在num_to_words 字典中找不到。

# Using .get() method with customised default value>>> num_to_words = {1: 'one', 2: 'two', 3: 'three'}>>> num_list = [1, 2, 3, 4, 5, 6]>>> word_list = [num_to_words.get(num, num) for num in num_list]>>> print(word_list)

6.defaultdict – 创建具有默认值的字典

另一种避免因查询字典中不存在的键而出现KeyError 的方法是使用内置的collections 模块中的defaultdict

使用defaultdict ,你可以指定一个 “默认值工厂”,这个函数可以为任何不存在的键返回我们想要的默认值。这里,我们在初始化一个defaultdict 对象时,使用一个lambda 函数来做这件事。

>>> num_to_words_dd = defaultdict(lambda: "Uh oh... key is not found in `defaultdict`!")>>> num_to_words_dd[1] = 'one'>>> num_to_words_dd[2] = 'two'>>> num_to_words_dd[3] = 'three'>>> print(num_to_words_dd)

当查询一个defaultdict对象中存在的键时,它与普通的字典对象没有什么区别。为了说明defaultdict 的工作原理,下面的代码片断使用了方括号,而不是.get() 方法。

>>> num_to_words_dd[2]

然而,如果你查询一个不存在的键,默认值会被返回。

>>> num_to_words_dd[5]

你也可以用intlist 关键字来初始化一个defaultdict 。如果你用int 来初始化它,那么就会创建一个默认值为0的defaultdict对象。当你查询一个不存在的键时,它会返回0。

>>> counter = defaultdict(int)>>> lst = [0, 1, 2, 2, 3, 1, 1, 0]>>> for num in lst:...     counter[num] += 1>>> print(counter[0]) # Key that exists>>> print(counter[5]) # Key that does not exist

同样地,如果你用list 来初始化它,那么一个defaultdict对象被创建,默认值为空列表,查询一个不存在的键会返回[]

>>> country_list = [('AU','Australia'), ('CN','China'), ...                 ('FR','France'), ('SG', 'Singapore'), ...                 ('US', 'United States'), ('PT', 'Portugal')]>>> country_dict = defaultdict(list)>>> for code, country in country_list:...     country_dict[code].append(country)>>> print(country_dict['AU']) # Key that exists>>> print(country_dict['BX']) # Key that does not exist

总而言之,只要你需要创建一个字典,并且每个元素的值都需要有一定的默认值,那么defaultdict 就是一个很好的选择。

7.用sorted() 以任何方式排序

如果你想对一个可迭代的东西进行排序,比如一个列表、一个字符串或一个元组,你可以使用sorted() 函数。它返回一个带有原始元素的排序方式的列表,而不改变原始序列。

对于字符串,它返回一个字符列表,以标点符号或空格为先,然后是按字母顺序排列的大写字母和小写字母。

>>> sorted("Hello, World!")

对于数字列表,它返回一个按升序排序的序列。

>>> sorted([5, 2, 4, 1, 3])

对于字符串列表,它返回一个按字母顺序排序的序列,以第一个字符为基础。

>>> fruits = ["apple", "watermelon", "pear", ...           "banana", "grapes", "rockmelon"]>>> sorted(fruits)

你也可以通过在sorted() 函数中指定reverseTrue 来反转这个序列。

>>> sorted(fruits, reverse=True)

你还知道你可以自定义你希望对迭代器进行排序的方式吗?你可以指定一个函数并将其分配给sorted 函数中的key 参数。例如,如果你想按每个词的长度以升序对fruits 列表进行排序,你可以这样做。

>>> sorted(fruits, key=len)

或者,如果你想按每个词中字母 “n “的数量对水果进行排序,你可以这样指定一个lambda 函数。

>>> sorted(fruits, key=lambda x: x.count('n'))

我们也可以通过引用另一个迭代器来进行排序。在下面的例子中,我们根据prices 字典将水果按价格递增进行排序。

>>> prices = {"apple": 1.4, "watermelon": 4, "pear": 1.2, ...           "banana": 2.3, "grapes": 3.5, "honeydew": 2.6}>>> sorted(fruits, key=lambda x: prices.get(x))

好了!现在就到此为止了。谢谢你走到这一步。我希望你已经学会了编写优雅代码的简单技巧,并最大限度地利用了 Python 中鲜为人知的内置函数和模块。

对于其中的一些技巧,我只是触及了表面;它们可以单独写成一篇文章。因此,我强烈建议你查看更多的相关资源以了解更多。

参考资料

  1. Python问题解决训练营2021,Rodrigo Girão Serrão
  2. Enumerate me, Pydon’t, 2021年4月6日, Rodrigo Girão Serrão
  3. Python中的解包。超越平行赋值,2021年9月19日,Leodanis Pozo Ramos
Want to Connect?

Python经验分享

学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

Python学习路线

这里把Python常用的技术点做了整理,有各个领域的知识点汇总,可以按照上面的知识点找对应的学习资源。
编写优雅代码的7个不太为人所知的Python技巧

学习软件

Python常用的开发软件,会给大家节省很多时间。
编写优雅代码的7个不太为人所知的Python技巧

学习视频

编程学习一定要多多看视频,书籍和视频结合起来学习才能事半功倍。
编写优雅代码的7个不太为人所知的Python技巧

100道练习题

在这里插入图片描述

实战案例

光学理论是没用的,学习编程切忌纸上谈兵,一定要动手实操,将自己学到的知识运用到实际当中。
编写优雅代码的7个不太为人所知的Python技巧
最后祝大家天天进步!!

上面这份完整版的Python全套学习资料已经上传至CSDN官方,朋友如果需要可以直接微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】。

编写优雅代码的7个不太为人所知的Python技巧今天的文章编写优雅代码的7个不太为人所知的Python技巧分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/66335.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注