How to process a string in a subscription layer

This is an example of a form, I will try to explain it in words later. I have a list from line breaks ...

they say

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

where b is criterion 1 and c is criterion 2

I want to break it into a list as follows:

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

So, I want to process the line in such a way that when I go through it, if the element meets the criteria 1, open a new list, if the element meets the criteria 2, close the list and return one level higher.

I tried to do something similar, but it does not work very well.

 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. 

I saw a split list to equal the size of the list before stackoverflow, but not one hack in the sublist using a set of criteria.

I'm new to python, so I'm not too familiar with data structures and iterator tools.

+8
python list recursion sublist
source share
7 answers

here you go:

 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))) 
+10
source share
 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) 

The above will work as long as your delimiters b and c are balanced; in particular, if you have excess c s, you will have an insufficient stack.

While I often like recursive solutions, this has the advantage that the core of the stack, which in this case, in my opinion, simplifies the code.

+1
source share

with stack:

 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] 

it will break if more b

+1
source share

There are very good answers to this question, I especially liked the thg435 regression solution using generators and the Marcin iterative solution, which adds elements to the list of links.

I also found that some solutions modify the input list or use global state. This, IMHO, is contrary to the true spirit of a recursive solution. The following is my attempt at a purely functional recursive solution in Python - provided, there are much more idiomatic and efficient ways to solve this problem, but I would like to write an answer, since I would write it in a purely functional programming language:

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

Some notes:

  • I do not use local variables or global variables, only function parameters for tracking state
  • I do not use assignment operators
  • Iterators or loops are not used to traverse the list of input data, only recursion
  • This is a tail recursive solution, although it has nothing to do with Python
  • Only expressions are used; operations like append or extend (which return None ) are avoided
  • No lists are changed (including the input list), instead, new lists are created as needed (using arrays for this)
  • This is a rather short and elegant solution, but it may be a subjective opinion :)
+1
source share

This will do the following:

 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) 

Note that this has the side effect of changing l . It is trivial to change by making a copy.

0
source share

In real recursion mode, you can do the following:

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

Pay attention to the use of global variables. A number of critics may object to it as a bad coding style.

0
source share
 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'] 
0
source share

All Articles