Python 拾遗录

Python 拾遗录

这篇文章记录使用 Python 碰到的一些有意思的东西. 时时更新.

变量的值交换

Python 里的变量值交换很简洁, 比如我要交换变量 ab 的值, 可以直接写

a, b = b, a

需要注意, 这里的交换顺序显然不是

a = b
b = a

而是用元组给 ab 赋值

tmp = (b, a)
a = tmp[0]
b = tmp[1]

另外, 最近和朋友聊天, 谈到位运算, 说了说用异或实现不借助中间变量的变量值交换. 过程是这样的

a = a ^ b
b = a ^ b  # 此时 b = a ^ b ^ b = a ^ (b ^ b) = a ^ 0 = a
a = a ^ b  # 此时 a = a ^ b ^ a = b ^ (a ^ a) = b ^ 0 = b

异或:

  • 相同为 0, 不同为 1
  • 可以交换
  • 可以结合
  • 任何值异或 0 不变.
    好像没有太多实用的地方? 但挺好玩的.

生成器

以前我们学过可以用带有递推性质的函数来构建一个生成器, 让我们的数据随要随算, 避免存储大量的数据. 简单来说, 它的实现是把函数语句中 “return 递推出来的结果” 改成 “yield 递推出来的结果”. 然后用这个 “函数” 构造一个实例, 每一次可以用 next() 得到该实例的下一个值, 不过一般可以直接用 for 访问. 例如

def odd():
    n = 1
    while True:
        yield n  # 每一次调用, 会从上一次的 yield 继续
        n += 2
    return None  # 用了 while True, 是不会走到这一步的

oddNums = odd()  # 得到一个生成器

for _ in range(5):
    print(next(oddNums))

生成器是迭代器 (Iterator) 的一种, 迭代器就是可以用 next 不断得到下一个值的这种对象.

map

我们经常用 map 把一个函数作用到一个可迭代对象上, 得到的是一个迭代器. 基本为了实用, 常常要再加一句 list() 把它转成列表.

def f(x):
    return x * x

iterFx = map(f, [x for x in range(5)])  # 这时的 iterFx 是个迭代器, 没法直接索引元素. 
Fx = list(iterFx)

lambda 表达式

lambda 表达式在 Python 里经常出现, 例如

f = lambda x: x * x
print(f(4))
print(list(map(f, [i for i in range(1, 6)])))

就可以把它看成是一个简短的函数定义, 它的参数和定义普通函数时候是一致的. 使用体验上有些类似 MATLAB 里的句柄函数.

但我很少有必须要用到它的时候, 感觉似乎只是为了代码的简洁? 还是说它在某个方面有过优化, 比直接定义一个函数要好?

可以用 lambda 表达式简洁地给出一些感受上有一点点 “违背” 函数传入参数规则的函数定义, 比如

def testFun(n=4):
    return lambda x: x + n 

testFun()(3)

实际上是函数里套了个函数, 但用起来有种默认参数在前面的感觉. 当然, 这种事情完全可以直接通过真的在函数里面定义一个函数来实现. 所以我还是感觉这个 lambda 表达式只起到了缩短代码量的作用.

位运算判断奇偶

奇数的二进制最后一位是 1, 所以可以用与运算 a & 1 判断 a 是不是奇数, 会稍微快一些.

类和实例的属性方法动态定义

在 Python 里可以动态给类和实例绑定属性或方法, 很方便. 可以在定义类的时候用 __slots__ 来限制实例可以绑定些什么属性.

双下划线开头的属性是私有的, 虽然实际上仍然可以访问, 就看使用者有没有守规矩了.

defaultdict

从 collections 里可以导入这个模块, 它是另一种字典, 可以指定默认的值的类型. 在未初始化某个键对应的值时, 会自动给这个键创建一个指定类型的值. 如

from collections import defaultdict

test = defaultdict(list)
test["omg"].append(1234)
print(test)
print(test["omg"])

结果为

defaultdict(<class 'list'>, {'omg': [1234]})
[1234]

和 lambda 表达式结合, 可以嵌套多个字典.

test = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))
test["aaa"]["aa"]["a"].append(1234)
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值