你好,我是悦创。今天我想和你分享的主题是:metaclass,是潘多拉魔盒还是阿拉丁神灯?
Python 中有很多黑魔法,比如今天我将分享的 metaclass。我认识许多人,对于这些语言特性有两种极端的观点。
- 一种人觉得这些语言特性太牛逼了,简直是无所不能的阿拉丁神灯,必须找机会用上才能显示自己的 Python 实力。
- 另一种观点则是认为这些语言特性太危险了,会蛊惑人心去滥用,一旦打开就会释放“恶魔”,让整个代码库变得难以维护。
你好,我是悦创。今天我想和你分享的主题是:metaclass,是潘多拉魔盒还是阿拉丁神灯?
Python 中有很多黑魔法,比如今天我将分享的 metaclass。我认识许多人,对于这些语言特性有两种极端的观点。
你好,我是悦创。
我们先来阅读下面的代码:
def remove_all(L, x):
assert type(L) is list and x is not None
for i in L:
if i == x:
print(f"i: {i}-L: {L}")
L.remove(i)
else:
print(f"i: {i}-L: {L}")
# pass
return L
print(remove_all([9, 9, 1, 9, 8, 1], 9))
你好,我是悦创。
Python字典表达式(也叫字典推导式)是一种简洁的方法来创建字典。它类似于列表推导式,但是用于生成字典对象。
以下是一个简单的例子。假设我们想要基于一个列表生成一个字典,其中列表的元素作为字典的键,并且值是该元素的平方:
numbers = [1, 2, 3, 4, 5]
squared_dict = {x: x**2 for x in numbers}
print(squared_dict)
你好,我是悦创。
二叉树是一个有限元素的集合,这个集合要么是空集,要么是由一个称为根的元素以及两个不相交的、分别称为左子树和右子树的二叉树组成。
让我们使用文本来表示一个二叉树。
考虑这样一个简单的二叉树:
1
/ \
2 3
/ \ / \
4 5 6 7
# 定义二分查找函数,接受一个有序列表 arr 和一个目标值 x 作为参数
def binary_search(arr, x):
# 初始化两个指针 low 和 high
# low 指向数组的开始,high 指向数组的结束
low, high = 0, len(arr) - 1
# 当 low 指针不大于 high 指针时,循环继续
while low <= high:
# 计算中间索引 mid
mid = (low + high) // 2
# 如果 mid 位置的元素小于目标值 x
# 说明目标值在 mid 右边,所以更新 low 指针到 mid + 1
if arr[mid] < x:
low = mid + 1
# 如果 mid 位置的元素大于目标值 x
# 说明目标值在 mid 左边,所以更新 high 指针到 mid - 1
elif arr[mid] > x:
high = mid - 1
# 如果 mid 位置的元素等于目标值 x,直接返回 mid 索引
else:
return mid
# 如果循环结束还没有返回,说明目标值 x 不在列表中,返回 -1
return -1
# 示例测试
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # 一个已排序的数组
result = binary_search(arr, 5) # 在数组中查找数字5
# 输出查找结果
if result != -1:
print(f"元素在数组中的索引为 {result}")
else:
print("元素不在数组中")
你好,我是悦创。
装饰器一直以来都是 Python 中很有用、很经典的一个 feature,在工程中的应用也十分广泛,比如日志、缓存等等的任务都会用到。然而,在平常工作生活中,我发现不少人,尤其是初学者,常常因为其相对复杂的表示,对装饰器望而生畏,认为它“too fancy to learn”,实际并不如此。
今天这节课,我会以前面所讲的函数、闭包为切入点,引出装饰器的概念、表达和基本用法,最后,再通过实际工程中的例子,让你再次加深理解。
接下来,让我们进入正文一起学习吧!
你好,我是悦创。
在前面的第一大章节中,我们一起学习了 Python 的函数基础及其应用。我们大致明白了,所谓的传参,就是把一些参数从一个函数传递到另一个函数,从而使其执行相应的任务。但是你有没有想过,参数传递的底层是如何工作的,原理又是怎样的呢?
实际工作中,很多人会遇到这样的场景:写完了代码,一测试,发现结果和自己期望的不一样,于是开始一层层地 debug。花了很多时间,可到最后才发现,是传参过程中数据结构的改变,导致了程序的“出错”。
比如,我将一个列表作为参数传入另一个函数,期望列表在函数运行结束后不变,但是往往“事与愿违”,由于某些操作,它的值改变了,那就很有可能带来后续程序一系列的错误。
你好,我是悦创。
在前面的学习中,我们其实已经接触到了很多 Python 对象比较和复制的例子,比如下面这个,判断 a 和 b 是否相等的 if 语句:
if a == b:
...
你好,我是悦创。
转眼间,专栏上线已经三年了😂,而我们也在不知不觉中完成了第一大章基础篇的学习。我非常高兴看到很多同学一直在坚持积极地学习,并且留下了很多高质量的留言,值得我们互相思考交流。也有一些同学反复推敲,指出了文章中一些表达不严谨或是不当的地方,我也表示十分感谢。
大部分留言,我都在相对应的文章中回复过了。而一些手机上不方便回复,或是很有价值很典型的问题,我专门摘录了出来,作为今天的答疑内容,集中回复。
你好,我是悦创。
这是基础版块的最后一节。到目前为止,你已经掌握了 Python 这一门当代武功的基本招式和套路,走出了新手村,看到了更远的世界,有了和这个世界过过招的冲动。
于是,你可能开始尝试写一些不那么简单的系统性工程,或者代码量较大的应用程序。这时候,简单的一个 py 文件已经过于臃肿,无法承担一个重量级软件开发的重任。
今天这节课的主要目的,就是化繁为简,将功能模块化、文件化,从而可以像搭积木一样,将不同的功能,组件在大型工程中搭建起来。
你好,我是悦创。
前面几节,我们一起学习了列表、元组、字典、集合和字符串等一系列 Python 的基本数据类型。但是,如何把这一个个基本的数据结构类型串接起来,组成一手漂亮的代码呢?这就是我们今天所要讨论的“条件与循环”。
我习惯把“条件与循环”,叫做编程中的基本功。为什么称它为基本功呢?因为它控制着代码的逻辑,可以说是程序的中枢系统。如果把写程序比作盖楼房,那么条件与循环就是楼房的根基,其他所有东西都是在此基础上构建而成。
毫不夸张地说,写一手简洁易读的条件与循环代码,对提高程序整体的质量至关重要。
你好,我是悦创。
世纪之交的论坛上曾有一句流行语:在互联网上,没人知道你是一条狗。互联网刚刚兴起时,一根网线链接到你家,信息通过这条高速线缆直达你的屏幕,你通过键盘飞速回应朋友的消息,信息再次通过网线飞入错综复杂的虚拟世界,再进入朋友家。抽象来看,一台台的电脑就是一个个黑箱,黑箱有了输入和输出,就拥有了图灵机运作的必要条件。
Python 程序也是一个黑箱:通过输入流将数据送达,通过输出流将处理后的数据送出,可能 Python 解释器后面藏了一个人,还是一个史莱哲林?No one cares。
你好,我是悦创。
很多朋友最开始学编程的时候,是从 C++ 或者 JAVA 语言入手的。他们好不容易磕磕绊绊地搞懂了最基本的数据类型、赋值判断和循环,却又迎面撞上了 OOP (object oriented programming) 的大墙,一头扎进公有私有保护、多重继承、多态派生、纯函数、抽象类、友元函数等一堆专有名词的汪洋大海中找不到彼岸,于是就放弃了进阶之路。
相比之下,Python 是一门相对友好的语言,它在创立之初就鼓励命令交互式的轻量级编程。理论上,Python 的命令式语言是图灵完备的, 也就是说命令式语言,理论上可以做到其他任何语言能够做到的所有的事情,甚至进一步,仅仅依靠汇编语言的 MOV 指令,就能实现图灵完备编程。
你好,我是悦创。
二分查找(Binary Search),是一种效率较高的查找方法。在面试或算法竞赛中,查找相关的问题最优解通常就是二分查找。特别在现场面试中尤其重要,常用二分查找来考察面试者的编码能力和算法思维。
二分查找也称为折半查找。如果一个查找问题能够用一个条件消除一半的查找区域,那么就对目标在特定空间搜索,从而减少查找空间。
边界处理!
虽然二分查找思路比较直观,但大部分面试者通常在边界处理的时候考虑不全,从而出错。
有很多原因导致二分查找处理边界失败!例如,当目标位于数组第0
个索引时,或位于第 (n - 1)
个索引时,程序进入死循环。
二分查找(Binary Search),是一种效率较高的查找方法。在面试或算法竞赛中,查找相关的问题最优解通常就是二分查找。特别在现场面试中尤其重要,常用二分查找来考察面试者的编码能力和算法思维。
二分查找也称为折半查找。如果一个查找问题能够用一个条件消除一半的查找区域,那么就对目标在特定空间搜索,从而减少查找空间。
该小课将对二分算法进行专题讲解,并结合二分变形问题深入学习二分算法,结合精心挑选的练习题,涵盖了算法中最常见的二分问题。 希望通过该课程,未来你应付各种面试并进一步提高算法思维。
什么是二分查找
二分复杂度分析
二分确定插入位置
寻找不动点
整数平方根
双向数组查找峰值
双向数组二分查找
数字出现次数统计
旋转数组寻找最小值
旋转数组二分查找
查找数组出现1次的数字
最终测验
你好,我是悦创。
实际工作生活中,我曾见到不少初学者编写的 Python 程序,他们长达几百行的代码中,却没有一个函数,通通按顺序堆到一块儿,不仅让人读起来费时费力,往往也是错误连连。
一个规范的值得借鉴的 Python 程序,除非代码量很少(比如 10 行、20 行以下),基本都应该由多个函数组成,这样的代码才更加模块化、规范化。
函数是 Python 程序中不可或缺的一部分。事实上,在前面的学习中,我们已经用到了很多 Python 的内置函数,比如 sorted()
表示对一个集合序列排序,len()
表示返回一个集合序列的长度大小等等。这节课,我们主要来学习 Python 的自定义函数。
你好,我是悦创。
l = None # 空 False
# not False >>> True
if not l:
print('ok')
else:
print('No')
print(not False)
你好,我是悦创。
星号 (*
) 可用于 Python 中的不同情况:
*args
, **kwargs
和关键字参数print(7 * 5)
print(2**4)
# ---output---
35
16