Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何将字符串处理为子列表层_Python_List_Recursion_Sublist - Fatal编程技术网

Python 如何将字符串处理为子列表层

Python 如何将字符串处理为子列表层,python,list,recursion,sublist,Python,List,Recursion,Sublist,这是示例表单,稍后我将尝试用文字进行解释。 我有一张断串的清单 说 其中b为标准1,c为标准2 我想把它分成如下列表: [a, a, a, [b, a, a, [b, a, c], a, [b, a, a, c], a, c], a] 所以我想处理字符串,这样当我遍历它时,如果该项符合条件1,则打开一个新列表,如果该项符合条件2,则关闭该列表并返回上面的一个级别 我试过这样做,但效果不太好 def sublist(self, l): for line in list: if not

这是示例表单,稍后我将尝试用文字进行解释。 我有一张断串的清单

其中b为标准1,c为标准2

我想把它分成如下列表:

[a, a, a, [b, a, a, [b, a, c], a, [b, a, a, c], a, c], a]
所以我想处理字符串,这样当我遍历它时,如果该项符合条件1,则打开一个新列表,如果该项符合条件2,则关闭该列表并返回上面的一个级别

我试过这样做,但效果不太好

def sublist(self, l):
  for line in list:
    if not b:
    self.data.append(line)
  else:
    sublist(l[line:])       #<-----  not sure how to recurse it.
def子列表(self,l):
对于列表中的行:
如果不是b:
self.data.append(行)
其他:
子列表(l[行:)#
只要您的
b
c
分隔符是平衡的,上述操作就可以工作;特别是,如果超过
c
s,则会出现堆栈下溢


虽然我经常喜欢递归解决方案,但这样做的好处是使堆栈显式,在我看来,在这种情况下,可以更容易地编写代码。

以下几点可以做到:

a, b, c = 1, 2, 3

def sublist(l):
  ret = []
  while l:
    val = l.pop(0)
    if val == b:
      ret.append([val] + sublist(l))
    else:
      ret.append(val)
      if val == c: break
  return ret

l = [a, a, a, b, a, a, b, a, c, a, b, a, a, c, a, c, a]
print l
print sublist(l)
请注意,这会产生修改
l
的副作用。通过复制来改变这一点很简单。

给你:

lst = "aaabaabacabaacaca"

def go(it):
    for x in it:
        if x == 'b':
            yield [x] + list(go(it))
        else:
            yield x
            if x == 'c':
                break 


print list(go(iter(lst)))
使用堆栈:

def parseList(inList):
    stack = [[]]
    for element in inList:
        if element == 'b':
            stack.append([element])
            stack[-2].append(stack[-1])
        elif element == 'c':
            stack.pop().append(element)
        else:
            stack[-1].append(element)
    return stack[0]

如果实际递归样式中的“c”多于“b”,则此操作将中断。您可以执行以下操作:

x = yourlist
i = 0
def lets_parse():
    global i
    fnlist = []
    while i < len(x)
        if x[i] == 'c':
            fnlist.append(x[i])
            i += 1
        return fnlist
        elif x[i] == 'b':
            i += 1
            f = lets_parse()
            f.insert(0, 'b')
            fnlist.append(f)
        else:
            fnlist.append(x[i])
            i += 1
return fnlist

print lets_parse()
x=yourlist
i=0
def让_解析():
全球i
fnlist=[]
而我

注意globals的用法。许多评论家可能会反对这种糟糕的编码风格。

这个问题有很好的答案,我特别喜欢thg435使用生成器的递归解决方案和Marcin的迭代解决方案,后者将元素添加到引用列表中

import ast    
mylist = '[a, a, a, b, a, a, b, a, c, a, b, a, a, c, a, c, a]'
mylist = mylist.replace('a','"a"')
mylist = mylist.replace('b','["b"')
mylist = mylist.replace('c','"c"]')
print ast.literal_eval(mylist)
#Output:
['a', 'a', 'a', ['b', 'a', 'a', ['b', 'a', 'c'], 'a', ['b', 'a', 'a', 'c'], 'a', 'c'], 'a']
我还发现一些解决方案修改输入列表或使用全局状态,这让我感到不安。这与递归解决方案的真正精神背道而驰。下面是我在Python中尝试的一种纯函数式递归解决方案——虽然有很多更惯用、更有效的方法来解决这个问题,但我想写一个答案,就像我用纯函数式编程语言写的那样:

# lst: the list to be processed
# acc: accumulated result
# stk: temporary stack
def process(lst, acc, stk):
    if not lst:
        return acc
    elif lst[0] == 'b':
        return process(lst[1:], [lst[0]], [acc] + stk)
    elif lst[0] == 'c':
        return process(lst[1:], stk[0] + [acc + [lst[0]]], stk[1:])
    else:
        return process(lst[1:], acc + [lst[0]], stk)

lst = ['a', 'a', 'a', 'b', 'a', 'a', 'b', 'a', 'c', 'a', 'b', 'a', 'a', 'c', 'a', 'c', 'a']
process(lst, [], [])
> ['a', 'a', 'a', ['b', 'a', 'a', ['b', 'a', 'c'], 'a', ['b', 'a', 'a', 'c'], 'a', 'c'], 'a']
需要注意的一些细节:

  • 我不使用局部变量或全局变量,只使用函数参数来跟踪状态
  • 我不使用赋值运算符
  • 没有迭代器或循环用于遍历输入列表,只有递归
  • 这是一个尾部递归解决方案,尽管这在Python中并不重要
  • 仅使用表达式;避免像
    append
    extend
    (返回
    None
    )这样的操作
  • 不会修改任何列表(包括输入列表),而是根据需要创建新列表(使用数组切片)
  • 这是一个相当简短而优雅的解决方案,但这可能是一个主观观点:)

不错。生成器确实简化了递归结构。请注意,这通过终止输出来处理“下溢”。这可能不是我想要的。这正是我想要的。谢谢。这个解决方案不起作用,以OP的问题中的例子为例,它产生了一个
索引器:列表索引超出范围
,实际上,这是一种糟糕的编码风格。在“实递归”中,不需要使用全局变量,结果作为递归函数的参数和返回值传递。
import ast    
mylist = '[a, a, a, b, a, a, b, a, c, a, b, a, a, c, a, c, a]'
mylist = mylist.replace('a','"a"')
mylist = mylist.replace('b','["b"')
mylist = mylist.replace('c','"c"]')
print ast.literal_eval(mylist)
#Output:
['a', 'a', 'a', ['b', 'a', 'a', ['b', 'a', 'c'], 'a', ['b', 'a', 'a', 'c'], 'a', 'c'], 'a']
# lst: the list to be processed
# acc: accumulated result
# stk: temporary stack
def process(lst, acc, stk):
    if not lst:
        return acc
    elif lst[0] == 'b':
        return process(lst[1:], [lst[0]], [acc] + stk)
    elif lst[0] == 'c':
        return process(lst[1:], stk[0] + [acc + [lst[0]]], stk[1:])
    else:
        return process(lst[1:], acc + [lst[0]], stk)

lst = ['a', 'a', 'a', 'b', 'a', 'a', 'b', 'a', 'c', 'a', 'b', 'a', 'a', 'c', 'a', 'c', 'a']
process(lst, [], [])
> ['a', 'a', 'a', ['b', 'a', 'a', ['b', 'a', 'c'], 'a', ['b', 'a', 'a', 'c'], 'a', 'c'], 'a']