Finding a list of nested string tuples in python

Let's say I have a list x:

x=['alfa[1]', 'bravo', ('charlie[7]', 'delta[2]'), 'echo[3]'] 

I want to create a new list that both smooths and removes the number enclosed in parentheses if the element has it. The result should be:

 x_flattened_bases = ['alfa', 'bravo', 'charlie', 'delta', 'echo'] 

Here is what I have now:

 x_flattened_bases = [] for item in x: if isinstance(item, tuple): x_flattened_bases.extend([value.split('[')[0] for value in item) else: x_flattened_bases.append(item.split('[')[0]) 

There is only 1 level of nesting in the list.

+4
source share
4 answers

Something like that:

 import collections import re def solve(lis): for element in lis: if isinstance(element, collections.Iterable) and not isinstance(element,str): for x in solve(element): yield re.sub(r"\[\d+\]",r"",x) else: yield re.sub(r"\[\d+\]",r"",element) x=['alfa[1]', 'bravo', ('charlie[7]', 'delta[2]'), 'echo[3]'] print list(solve(x)) 

output:

 ['alfa', 'bravo', 'charlie', 'delta', 'echo'] 
+4
source

Compression questions have been answered many times .

tl; dr use awful document ast module smoothing function

 >>> from compiler.ast import flatten >>> flatten([1,2,['dflkjasdf','ok'],'ok']) [1, 2, 'dflkjasdf', 'ok', 'ok'] 

One layer that is also removed [] (if all the child nodes are strings):

 >>> from compiler.ast import flatten >>>def flattenstrip(input): return [el[:el.find('[')] if el.find('[')!=-1 else el for el in flatten(input)] >>>flattenstrip(['alfa[1]', 'bravo', ('charlie[7]', 'delta[2]'), 'echo[3]']) >>>['alfa', 'bravo', 'charlie', 'delta', 'echo'] 
+3
source

This works, but it makes a lot of assumptions about the structure (i.e. only one level of nesting, string ) ...

 from itertools import chain lst = ['alfa[1]', 'bravo', ('charlie[7]', 'delta[2]'), 'echo[3]'] flattened = chain.from_iterable([x] if isinstance(x, str) else x for x in lst) result = [x.rsplit('[', 1)[0] for x in flattened] 

It becomes more accurate when you give concentrated operations a name:

 def flatten(it): return chain.from_iterable([x] if isinstance(x, str) else x for x in lst) def clean(it): return (x.rsplit('[', 1)[0] for x in it) result = list(clean(flatten(lst))) 

If you want to stay closer to the code, you can clear it using recursion.

 def process(lst, result=None): if result is None: result = [] for item in lst: if isinstance(item, str): result.append(item.rsplit('[', 1)[0]) else: process(item, result) return result result = process(lst) 

Edit

More concise thanks to @yoonkwon's inspiration, but note that compiler.ast deprecated and no longer exists in Python 3:

 from compiler.ast import flatten result = [item.rsplit('[', 1)[0] for item in flatten(lst)] 
+2
source

Smoothing and cleaning words are two separate tasks. Funcy library has flatten and re_find functions to solve them:

 from funcy import flatten, re_find flat_list = [re_find(r'^\w+') for word in flatten(your_list)] 

Or it can be done more efficiently with a few other functions:

 from funcy import iflatten, re_finder flat_list = map(re_finder(r'^\w+'), iflatten(your_list)) 
0
source

Source: https://habr.com/ru/post/1480142/


All Articles