这是该示例的形式,我会尽力后来解释它的话。 我从分手的字符串列表...
说
[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)
上面的代码将只要你的工作b
和c
分隔符是平衡的; 特别是,如果你有多余的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的无关
- 只有表达式中使用; 操作喜欢
append
或extend
(返回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