跳转至

Python编程答问

原文大多首发于知乎。

Python的id函数返回的是所储存对象的地址吗?#

比如 a = [1,2] 。 id(a)的值是列表 [1,2] 在内存中的地址, 而不是 a 的地址。

【答】

严格讲是“值的ID”。推广一下Thonny编辑器,它就是这么写的:

图上的“Heap”并不是指heap据结构,而是说:这是一堆供你分配和取消分配的内存空间;它们在方法或函数调用之外,或者在多个函数中共享。——而函数内变量的值/内存空间是在函数调用期间在stack中临时存储的。

将一个序列转成多维数组/嵌套列表#

两层列表解析

1
2
3
4
5
s = 'abcddssfdeee'
n = 4 # 每节长度
a = [[x for x in s[b:b+n]] 
    for b in range(0, len(s), n)]
print(a)

等价于:

1
2
3
4
5
6
7
s = 'abcddssfdeee'
n = 4 # 长度
begin = [b for b in range(0, len(s), n)]
a = []
for b in begin:
    a.append([x for x in s[b:b+n]])
print(a)

如何进行字母频率统计?#

【答】

1
2
3
>>> from collections import Counter
>>> c = Counter()
>>> c.update('hello, there!')

复制列表x为y,为什么改动x的时候,y也会变?#

【答】

浅拷贝一个列表,只是拷贝列表内第一层各元素的引用。如果这些引用指向的是可变对象(可以原址改动),那么此对象的更改会影响前后两个列表。

与此不同,深拷贝copy.deepcopy()能拷贝各层对象的值,获得独立的拷贝。

可变数据类型可以“原址改动”是说,改动后内存地址不变,不影响跟它绑定的所有变量;而一个绑定到不可变数据的变量一旦“改动”,就是重新绑定到一个新建的地址(新建或重用的地址;原址如果还有绑定则保留,如果没有则准备回收)。

不可变数据类型主要包括数值(int、float、bool)、字符串和元组,可变数据类型包括列表、字典等。

有些编辑器(如Thonny、VS Code的Jupyter Notebook模式)可以跟踪堆栈的地址和值。

评论