朋友和我分享一道面试题,说是“Python里有一些函数它的名字前后有下划线,然后他这是有一个专有名词的”。感觉自己学python略显粗糙,一些知识用过就过了,没想着去记忆它。正好最近一直在改代码,在面向remix编程的同时(doge,记录一下这些散散的知识点吧,当作积累!
师兄说这些都是面经,背一个月就都会了。现在最重要的是刷题,等后面确定方向后,那时候会有一个长长的pdf,需要自己去找,背诵八股文,就都会了。其实没有很多的。
1、import *
from Configurations import *
#导入所有内容,说明可以直接使用模块中定义的所有对象,不需要通过Configurations. 前缀来引用它们
这样子可以用在初始参数的设置上,代码和参数设置分离开来
但是小chat和老师都是这种方式不推荐,这是因为:
2、deep copy
self.initial_positions = deepcopy(config_initial_swarm_positions)
在 Python 中,`deepcopy` 函数是 `copy` 模块的一部分,用于创建一个对象的深层拷贝。在这个上下文中,`self.initial_positions = deepcopy(config_initial_swarm_positions)` 的作用是创建 `config_initial_swarm_positions` 变量的一个完全独立的副本,然后将这个副本赋值给 `self.initial_positions`。
深层拷贝与浅拷贝 (`copy`) 的区别在于:
1. **深层拷贝(Deep Copy)**:
- 创建一个新对象,然后递归地将原始对象中的所有成员复制到新对象中。
- 如果原始对象包含了对其他对象的引用,深层拷贝会创建这些对象的副本。
- 在深层拷贝之后,原始对象和新对象之间没有任何共享的实例。因此,修改其中一个对象不会影响另一个。
2. **浅拷贝(Shallow Copy)**:
- 只复制对象本身和其包含的元素,但不复制这些元素所引用的对象。
- 如果原始对象包含了对其他对象的引用,浅拷贝不会创建这些对象的副本,而是复制引用。
- 浅拷贝中,原始对象和副本可能会共享一些子对象。
在此代码中,使用 `deepcopy` 来初始化 `self.initial_positions` 意味着:
- `self.initial_positions` 将获得 `config_initial_swarm_positions` 的完整副本,包括其所有嵌套的对象。
- 之后,你可以修改 `self.initial_positions` 而不会影响 `config_initial_swarm_positions`。
这在处理可变对象(如列表或字典)并希望保持原始数据不变的情况下非常有用。
3、yield和return
`yield` 和 `return` 都是用于从函数中返回值的关键字,但它们在功能和用法上有重要的区别:
1. `return`:
- `return` 用于从函数中返回一个值,并且终止函数的执行。当函数执行到 `return` 语句时,它会立即结束,并将指定的值作为函数的结果返回给调用者。
- 函数只能使用 `return` 返回一次结果。如果在函数内部包含多个 `return` 语句,只有第一个被执行,其余的将被忽略。示例:
def add(a, b):
result = a + b
return result # 返回结果并结束函数的执行
result = add(2, 3) # 调用函数并获取返回值
print(result) # 输出结果为 5
2. `yield`:
`yield` 用于定义生成器函数,生成器函数可以迭代地产生值。当函数包含 `yield` 语句时,它变成了一个生成器函数,并且在调用时不会立即执行,而是返回一个生成器对象。
- 每次调用生成器的 `__next__()` 方法(或使用 `for` 循环迭代生成器)时,函数会执行到下一个 `yield` 语句,并将 `yield` 后面的值产生出来,然后暂停函数的执行状态,保存现场,等待下一次迭代。示例:
def generate_numbers():
yield 1
yield 2
yield 3
generator = generate_numbers() # 创建生成器对象
for num in generator:
print(num) # 依次输出 1, 2, 3
总结:
- `return` 用于普通函数,一次性返回结果并结束函数。
- `yield` 用于生成器函数,允许函数在多次迭代中产生值,并在每次 `yield` 后暂停执行状态,以便下一次迭代继续执行。这使得生成器函数能够高效地处理大量数据或无限序列,而不需要一次性将所有数据加载到内存中。
4、Python中,`*` 操作符的作用
在Python中,`*` 操作符用于解压(unpack)可迭代对象。在 `data.TensorDataset(*data_arrays)` 中,`*data_arrays` 的作用是将 `data_arrays` 中的元素解压成单独的参数,然后传递给 `data.TensorDataset` 构造函数。
`data_arrays` 似乎是一个包含多个数组或序列的可迭代对象(例如,列表、元组等)。通过使用 `*data_arrays`,你可以将它解压成独立的参数,传递给 `data.TensorDataset` 构造函数,而不需要一个一个手动提取这些参数。
例如,如果 `data_arrays` 是一个包含三个数组的元组,你可以这样使用 `*` 操作符:
data_arrays = (array1, array2, array3)
dataset = data.TensorDataset(*data_arrays)
这等效于以下代码:
dataset = data.TensorDataset(array1, array2, array3)
这种技术在函数调用时将可迭代对象的元素解压成独立的参数非常有用,可以简化代码并提高可读性。
5、add(self, *args)
方法
这个方法用于将传入的参数与 self.data
中的元素逐个相加。它使用了可变数量的参数 *args
,这意味着你可以传入任意数量的参数,每个参数都会与 self.data
中的相应元素相加,从而实现累加操作。
6、iloc和loc的区别
7、_作为占位符
hop_numbers_not_arrived = [config.MAX_TTL for _ in range(number_packets_not_arrived)]
在这个代码片段中,_
是一个占位符,用于表示列表构造函数中的循环变量。在 Python 中,列表构造函数 [config.MAX_TTL for _ in range(number_packets_not_arrived)]
中的占位符 _
会被替换为循环变量 i
,从而生成一个包含 number_packets_not_arrived
个 config.MAX_TTL
的列表。