总的来说,这是一个很好的学习经历。我不仅从组织者那里学到了大量的技巧,而且还从其他训练营学员那里学到了大量的技巧。大家都强调要最大限度地利用Python的内置函数和模块,以及编写干净和优雅的代码。
这篇文章既是我记录这些我学到的新技巧的方式,也是我与你分享它们的努力。它们帮助我大大提高了Python编程技能,我希望它们也能以同样的方式帮助你。你准备好了吗?让我们直接进入!
目录
- 被低估的
enumerate()
int()
函数比你想象的更有用- 让我们断言:
assert
语句! - 解压和打包–
*
操作符的力量 - 从字典中检索值?使用
.get()
并抛弃[]
! defaultdict
– 用默认值创建字典- 用任何你想要的方式排序
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]
你也可以用int
或list
关键字来初始化一个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()
函数中指定reverse
为True
来反转这个序列。
>>> 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 中鲜为人知的内置函数和模块。
对于其中的一些技巧,我只是触及了表面;它们可以单独写成一篇文章。因此,我强烈建议你查看更多的相关资源以了解更多。
参考资料
- Python问题解决训练营2021,Rodrigo Girão Serrão
- Enumerate me, Pydon’t, 2021年4月6日, Rodrigo Girão Serrão
- Python中的解包。超越平行赋值,2021年9月19日,Leodanis Pozo Ramos
Want to Connect?
Python经验分享
学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!
Python学习路线
这里把Python常用的技术点做了整理,有各个领域的知识点汇总,可以按照上面的知识点找对应的学习资源。
学习软件
Python常用的开发软件,会给大家节省很多时间。
学习视频
编程学习一定要多多看视频,书籍和视频结合起来学习才能事半功倍。
100道练习题
实战案例
光学理论是没用的,学习编程切忌纸上谈兵,一定要动手实操,将自己学到的知识运用到实际当中。
最后祝大家天天进步!!
上面这份完整版的Python全套学习资料已经上传至CSDN官方,朋友如果需要可以直接微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】。
今天的文章编写优雅代码的7个不太为人所知的Python技巧分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/66335.html