【发布时间】:2021-08-15 05:59:55
【问题描述】:
我有一个想要放入嵌套列表的函数和值列表。我希望结果是一个 LISP 样式列表(看起来接近某些 LISP 样式可执行代码的东西),我以后可以轻松处理。 该列表来自一个“句子”,它按单词拆分为一个列表 - 它通过首先检查数据库中的任何多单词标记,粘合它们然后稍后将它们分开,将定义的短语(多单词)保持在一起。 任何不在数据库中的单词都将被忽略。标点符号也被忽略。它只匹配实际存储的令牌。 这让我可以写一个可以翻译成我以后可以处理的函数的句子。 我们可以忽略这些是函数的事实,而将它们视为字符串,因为它们是这样存储的,但是函数和参数完美地描述了用例,因为它们就是这样。 函数将是列表中的第一项,然后是同一列表中的参数。 一个没有参数的函数将在一个只有那个元素的列表中。 一个本身是函数的参数将在一个列表中(如果有的话,还有它的参数)。 每个函数采用的参数数量是预设的,并且不会改变(它可以调用其他接受自己参数的函数)。 从技术上讲,应该能够无限深入,尽管我确信如果限制有帮助,几个级别就足够了。这是一个递归类型的问题,因此深度级别并不重要。 如果有帮助,我正在使用 Django,因此可以访问那里的任何模型方法,因为 Token 和句子一样是模型。
我将列表项称为“令牌”。它们可以不止一个词。它们实际上存储在数据库中。 每个 Token 可以有:symbol, val, kind 符号:在句子中搜索的漂亮格式字符串 价值:我们想要的东西在列表中 种类:整数;其他种类的参数或代码的数量
KIND_CHOICES = [ (0, 'Argless Function'), (1, '1-Arg Function'), (2, '2-Arg Function'), (3, '3-Arg Function'), (4, '4-Arg Function'), (6, 'Value'), (7, 'Ignore'), ]
让我们以这些令牌为例: ("符号",'val',种类)
("Walk",'walk',1) ("To",'to',1) ("Sandwich Shop",'sandwich-shop',6) ("Order",'place_order',2) ("Toasted",'toast',1) ("Sandwich",'sandwich',6) ("Dine-In",'here',0) ("Eat",'eat',1) ("Back",'back',1) ("Home",'residence',6) ("Nap",'sleep',0) ("on the sofa",7)
这是一个例句:
Walk To the Sandwich Shop, Order your favorite Toasted Sandwich for Dine-In, Eat your Sandwich, Walk Back Home, then finally Nap on the sofa.
我将从当前的工作清理函数中得到的第一个列表为我们提供:
['walk','to','sandwich-shop','place_order','toast','sandwich','here','eat','sandwich','walk','back','residence','sleep']
然后,最后(我无法正确的部分!我错了一个,得到重复,缺少标记或错误的结构)
[['walk',['to','sandwich-shop']],['place_order',['toast','sandwich'],['here']],['eat','sandwich'],['walk',['back','residence']],['sleep']]
我的一些尝试涉及使用重复的占位符字符串作为参数,以及各种 replace_or_append 实现尝试;在参数列表中插入空元素,然后使用 put_in_next_empty_spot 实现(尝试几次);以及一些带有递增索引和弹出的更简单的循环。 我只是因为某种原因被困在这个问题上,并且可以使用一些脑力来解决看起来应该是一个非常简单的问题。
以下是一次非常失败的尝试中的一些示例代码:
def nest(self, token, l, idx):
if token.is_func:
result = [token.val]
if token.arg_count:
for i in range(token.arg_count):
idx += 1
f = self.funcs.pop(idx)
t = self.get_token(f)
result = self.nest(t,result,idx)
l.append(result)
else:
l.append(token.val)
return l
def nestify(self):
nested = []
for i, s in enumerate(self.funcs):
token = self.get_token(s)
nested = self.nest(token,nested,i)
return nested
我使用了一些我添加到 Token 的便捷方法来检查它的 .kind 属性(整数),获取 Token 对象等。[self.funcs] 这是上面提到的第一个函数列表(清理平面列表)。
原句:
"Walk To Sandwich Shop Dine-In Nap"
变成(这行得通,也是我们想要的):
['walk', 'to', 'sandwich-shop', 'here', 'nap']
应该变成:
[['walk', ['to', 'sandwich-shop']], ['here'], ['nap']]
但不幸的是,我得到:
['walk', ['to', ['here'], ['nap']], 'sandwich-shop']
为了帮助阐明输出的外观,当我处理整个列表时,我会说“列表中的第一项是一个函数”。这样,如果它是一个单项列表,它可以只调用该函数,如果它是一个多项列表,我们知道剩余的项(或项列表)是该函数的参数。
使用上面较长句子示例中我们想要的输出列表:
[['walk',['to','sandwich-shop']],['place_order',['toast','sandwich'],['here']],['eat','sandwich'],['walk',['back','residence']],['sleep']]
如果我们取第一个项目(列表):
['walk',['to','sandwich-shop']]
我们将处理传入一个 arg 的“walk”函数:评估函数“to”的结果,将参数“sandwich-shop”传递给它。
如果我们取第二项(另一个列表):
['place_order',['toast','sandwich'],['here']]
我们将调用 'place_order' 传递给它想要的两个参数:第一个将是评估 'toast' 函数的结果,将 'sandwich' 传递给 'toast'。 'place_order' 的第二个参数将是调用/评估 'here' 的结果。
希望这是有道理的。 :)
这里的任何帮助将非常感激!虽然我是新来的,但我已经阅读了发布问题的介绍,并希望能提供所需的一切。
谢谢!
快乐
【问题讨论】:
-
请提供预期的minimal, reproducible example (MRE)。我们应该能够复制和粘贴您的代码的连续块,执行该文件,并重现您的问题以及跟踪问题点的输出。这让我们可以根据您的测试数据和所需的输出来测试我们的建议。显示中间结果与您的预期不同的地方。您发布的代码定义了两个函数并在不调用任何一个的情况下停止。
-
请从intro tour 重复on topic 和how to ask。您的大部分帖子都是对您的项目的描述,其中大部分与手头的问题无关。转储多余的部分,正确跟踪您的代码,并发布错误点周围的证据。
-
我已经这样做了。如果不是,请更具体。
-
在你想要的第一个输出中,它不应该是像
[['walk', [['to', ['sandwich-shop']], ['place_order', [['toast', ['sandwich']], ...], ...]这样的东西,因为to是一个单参数函数,所以它应该消耗sandwich-shop(或者,就此而言,place-order)?您能否澄清to没有被列为带有参数的自己的函数,而是列为Value? -
我想你可能是对的 AJAX!我可能已经为此工作了很长时间,我只是在这一点上让它变得更糟。
标签: python list recursion lisp nested-loops