如何处理字符串转换成子列表层(How to process a string into layer

2019-09-16 23:29发布

这是该示例的形式,我会尽力后来解释它的话。 我从分手的字符串列表...

[a, a, a, b, a, a, b, a, c, a, b, a, a, c, a, c, a]

其中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.

我见过破列表分为大小相等的名单之前,计算器,却没有一个使用了一套标准闯入子表。

我是相当新的蟒蛇,所以我不是太熟悉数据结构和迭代器工具。

Answer 1:

干得好:

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)))


Answer 2:

addlist = []
alllists = []
for item in mylist:
    if item == b:
       newlist = [item]
       addlist.append(newlist)
       alllists.append(addlist)
       addlist = newlist
    elif item == c:
       addlist.append(item)
       addlist = alllists.pop()
    else:
       addlist.append(item)

上面的代码将只要你的工作bc分隔符是平衡的; 特别是,如果你有多余的c S,你将有一个堆栈溢出。

虽然我经常喜欢递归的解决方案,这有使栈明确,在这种情况下,在我看来,导致更容易神交代码的优势。



Answer 3:

有此问题的非常好的答案,我特别喜欢用发电机和马辛的这增加的元素引用列表迭代求解thg435的递归解决方案。

我还发现令人不安的是一些解决方案修改输入列表,或者使用全局状态。 也就是说,恕我直言,违背了递归解决方案的真正精神。 下面是我尝试在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的无关
  • 只有表达式中使用; 操作喜欢appendextend (返回None避免)
  • 没有名单是不断修改(包括输入列表),而不是为(使用数组切片)需要创建新的列表
  • 这是一个相当短而优雅的解决方案,但可能是一个主观的意见:)


Answer 4:

用栈:

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的



Answer 5:

下面将做到这一点:

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 。 这是微不足道的通过复印来改变这种状况。



Answer 6:

在实际的递归式的,你可以做到以下几点:

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()

注意使用全局变量。 一些批评者可能会反对它坏的编码风格。



Answer 7:

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']


文章来源: How to process a string into layer of sublists