Mid节奏_列表_乘法_空列表_None_打击乐音轨_动次打次
回忆
- 上次我们了解 列表加法
- 对 相加结果 赋值 - lst1 = lst1 + lst2 - 加法的本质 是 将两个列表 拼接 - 并将 结果位置 赋给帧(frame)上的变量 来引用
- 对列表 进行扩充 - 3种做法
- lst1 += lst2
- lst1[-1:] = lst2
- lst1.extend(lst2)
- 上述 2类方法 结果相同
- 但是稍有区别
- 结果
地址
- 会改变l1地址
- 后三种不改变地址
效率不同
- 后三种效率高
- 直接扩展列表

- 既然 有 列表
加法
- 那有 列表
乘法 吗?🤔
回忆字符串
"oeasy" * 2
"oeasy" * 22
- 字符串乘法
- 本质是累加

- 列表 也有 乘法 吗?
列表乘法
[1] * 9
[1] * 99
[1] * 999

- 最大能有多少个元素呢?
试探边缘
[1] * 99999
- 5个9好像也没有问题

- 没有问题就继续试探
边缘
- 8个9 可以接受
- 但很犹豫
[1] * 99999999
- 总有物理内存的极限
- 会分不出来 这么大空间的

- 如果想要清空列表呢?
清空列表
- 将 列表 清空
- 就 得到 空列表
- []
lst = [1]
lst.clear()
- 或者直接用空列表赋值
lst = []
- 空列表 对象 彼此 相等吗?
建立空列表
a = []
b = []
- 我建立了两个空列表

- 他们 虽然 都是空列表
- 但引用 不同空间
- 可以让他们地址相同吗?
连等赋值
- a = b = [ ] 这句完成两个任务
- b = [ ]
- a = b
- 两个空列表对象
- 都指向 同一位置了

- 空列表
- 是空的列表
- 不是 真空
- 还想让他 真空?!😺
None
lst1 = None
lst2 = None
id(lst1), id(lst2), id(None)
type(None)
help(None)
- None 的意思是
- 啥也不是
- 不是数字
- 不是字符串
- 不是列表
- 啥也不是

- None的类型是
- NoneType
- 啥类型也不是
- 帮助说啥呢?
NoneType
- 帮助里 啥也没说


- None 还是
啥也不是
啥也不是
lst1 = None
lst2 = None
lst1 == lst2
lst1 is lst2
- 因为他俩
都 啥也不是

- 啥也不是
- 只有一个

- 位置相同
- 所以相等了
None的地址
- 所有None的地址相同
- 都是id(None)
- 可以打印观察
- print(id(None))

|
特征 |
None |
[ ] |
|
类型 |
空值类型 (NoneType) |
空列表类型 (empty list) |
|
引用位置特性 |
所有引用均指向同一内存位置(单例对象) |
每次创建的[]均指向不同内存位置(独立实例) |
|
示例验证(Python) |
a = None b = None a is b → True |
a = [] b = [] a is b → False |
- 空列表 和 None 有
区别吗?
区别
|
方法/操作 |
核心功能 |
|
clear() |
清空列表内所有元素, 使列表变为空列表 |
|
空列表赋值(=[]) |
直接将列表重新赋值为空列表, 生成新的空列表对象(内存地址改变) |
|
None赋值(=None) |
将列表指向None(空对象), 此时列表不再指向任何列表实例, 与空列表本质不同 |
- 空列表也可以有乘法吗
空列表
[] * 3
[] + [] + []
- 要 乘的 是 列表里面的 列表项
- 里面 没有 列表项
- 乘来乘去 还是空的

- 非空列表 乘法
啥样 呢?
非空列表
- 列表 里面有东西
- 乘出来
- 列表项 就翻倍
[3] * 3
[3] + [3] + [3]
- 空列表 不是 空
[[]] * 3
[[]] + [[]] + [[]]
- 乘出来 也翻倍

- 这怎么理解?
空列表作为列表项
- []是空列表
- 长度为0
- 是一个 对象
- 有自己的专门地址

- [[]]
- 是 列表
- 列表 长度为1
- 列表项为列表
- 列表的列表
- 叫做 二维列表
二维列表 降维
- 通过索引 可以获得 列表项

- [[]]的第0个元素为[]

- [[]] * 3
- 就将这唯一的列表项[]
- 复制3次
- 还放在列表里
- 就是[[], [], []]
- 这个列表
- 不为空
- 有三个元素
- 三个元素都是 空列表
- 乘法的结果
- 可以 赋值 吗?
乘法结果 赋值
lst = [1]
id(lst)
lst = lst * 3
id(lst)
- 直接赋值
- 就直接把 原引用的地址 改了

- 乘法也可以增强赋值吗?
增强赋值
- 回忆增强赋值
- +=
lst = [1]
id(lst)
lst += lst
id(lst)
lst *= 3
id(lst)
- 增强赋值
- 还使用 原来引用的地址
- 速度快
- 效率高
- 规则 和 加法赋值 一样

- 列表乘法
- 有什么
应用场景吗?
打击乐音轨

import mido
from mido import Message, MidiFile, MidiTrack
# 设置每拍的 ticks 数
ticks_per_beat = 960
# 设置速度为 120 BPM
tempo = mido.bpm2tempo(120)
# 定义动次打次节奏的音符编号(打击乐器组)
rhythm_notes = [36, 42, 38, 42] # 底鼓、踩镲、军鼓、踩镲
# 创建 MIDI 文件和音轨
mid = MidiFile(ticks_per_beat=ticks_per_beat)
track = MidiTrack()
mid.tracks.append(track)
# 添加速度信息
track.append(mido.MetaMessage('set_tempo', tempo=tempo, time=0))
# 设置为打击乐器组(通道 10,MIDI 中编号为 9,因为从 0 开始)
track.append(Message('program_change', program=0, channel=9, time=0))
# 添加节奏音符(所有音符发送到通道 10)
for note in rhythm_notes:
track.append(Message('note_on', note=note, velocity=80, channel=9, time=0))
track.append(Message('note_off', note=note, velocity=80, channel=9, time=ticks_per_beat))
# 添加音轨结束信息
track.append(mido.MetaMessage('end_of_track', time=0))
# 保存 MIDI 文件
mid.save('rhythm_midi.mid')
生成效果
|
底鼓 |
踩镲 |
军鼓 |
踩镲 |
|
咚 |
次 |
哒 |
次 |


- 在线编辑midi
清空节奏
# 定义动次打次节奏的音符编号(打击乐器组)
rhythm_notes = [36, 42, 38, 42]
- 如果想把这个节奏循环3遍
# 定义动次打次节奏的音符编号(打击乐器组)
rhythm_notes = [36, 42, 38, 42] * 3
- 这样就可以 循环3遍

- 3遍之后 底鼓叠音

- 该怎么做呢?
叠音
rhythm_notes = [36, 42, 38, 42] * 3 + [36, 36, 38, 42]
- 如果想要这个套路 多循环几次
rhythm_notes *= 10
- 最终效果

总结
- 这次我们 了解了
- 列表的 乘法运算
- 乘法的本质 是 累加
- 规则 和加法类似
- 数据特别大时
- 会抛异常

- 列表 还有啥好玩的 吗?🤔
- 下次再说 👋
浙公网安备 33010602011771号