oeasy教python109-Mid节奏_列表_乘法_空列表_None_打击乐音轨_动次打次

Mid节奏_列表_乘法_空列表_None_打击乐音轨_动次打次

回忆

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

图片描述

  • 既然 有 列表​​加法​
  • 那有 列表​​乘法​​ 吗?🤔

回忆字符串

"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 = [ ] 这句完成两个任务
  1. b = [ ]
  2. 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
  • 最终效果

图片描述

总结

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

图片描述

  • 列表 还有啥好玩的 吗?🤔
  • 下次再说 👋
posted on 2025-12-09 11:57  overmind1980  阅读(0)  评论(0)    收藏  举报