python - 如何在 python 中处理解析和树处理任务?(代表节奏)
问题描述
我有一个音乐节奏的私人符号,它看起来像--(---)- 表示节拍、节拍、三连音、节拍。括号将单个节拍分成与其包含的一样多的部分。
它是递归的,所以例如 --((--)(--))- 意味着与 --(----)- 相同
我正在尝试解析这些字符串并将它们转换为音符持续时间,我发现它在 python 中非常困难。
一个例子应该是这样的:
string="--(-(--))-(--(--))---(--)(-)"
->
tree=[1,1,[1,[1,1]],1,[1,1,[1,1]],1,1,1,[1,1],[1]]
->
inversedurations= [1,1,2,4,4,1,3,3,6,6,1,1,1,2,2,1]
pyparsing 似乎很容易完成实际的困难:
import pyparsing
parsed=(pyparsing.nestedExpr().parseString("("+string+")").asList())[0]
['--', ['-', ['--']], '-', ['--', ['--']], '---', ['--'], ['-']]
但是当谈到把它变成上面的树时,只需用 1,1 替换字符串 '--' 我正在尝试像在 lisp 中那样编写递归、映射和连接列表,但我只是卡住了。
谁能告诉我在python中做这些事情的好方法?lisp 风格是否容易过时,或者是否有一些聪明的事情可以用生成器和理解来代替?
解决方案
我不确定我是否正确理解了你的问题。您想将输出从pyparsing
问题中所述的树结构转换吗?如果是,您可以执行以下操作:
lst = ['--', ['-', ['--']], '-', ['--', ['--']], '---', ['--'], ['-']]
def convert(lst):
for item in lst:
if isinstance(item, str):
yield from (1 for i in item)
else:
yield [*convert(item)]
print(list(convert(lst)))
印刷:
[1, 1, [1, [1, 1]], 1, [1, 1, [1, 1]], 1, 1, 1, [1, 1], [1]]
推荐阅读
- android - 文本视图中的内容未显示(Android Studio)
- javascript - 如果更改语句的顺序,为什么代码不起作用?
- php - 将1000万条mysql记录以特定格式迁移到MongoDB的策略
- database - Laravel - 如何与从属数据库进行数据库连接
- node.js - 如何使用nodeJS检查PDF中的复选框?
- git - “冲突文件”并且该文件不是我的发布分支的一部分
- servicestack - 如何从 ServiceStack API 获取访问令牌
- angular - Angular & svg - 找不到 Angular 的任何 SVG 标签
- bash - cli和jq,如何在使用unique_by过滤后获取属性值
- java - 如何正确调整大图像的大小?