4

假设我有一个列表 x:

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

我想创建一个新列表,如果该项目有一个,则该列表会展平并删除括号内的数字。结果应该是:

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

这是我目前拥有的:

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

列表中只有 1 级嵌套。

4

4 回答 4

4

像这样的东西:

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

输出:

['alfa', 'bravo', 'charlie', 'delta', 'echo']
于 2013-05-10T16:22:37.787 回答
3

扁平化的问题已经回答了很多次

tl;博士使用可怕的文档ast模块的 flatten 功能

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

一个也去掉 [] 的单行代码(假设所有子节点都是字符串):

>>> 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']
于 2013-05-10T17:19:41.447 回答
2

这行得通,但它对结构做了很多假设(即只有一层嵌套,string仅限s)......

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] 

当您为重点操作命名时,它会变得更加整洁:

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

如果你想更接近你拥有的代码,你可以使用递归来清理它。

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)

编辑

感谢@yoonkwon 的启发,更简洁,但请注意,compiler.ast它已被弃用,并且在 Python 3 中不再存在:

from compiler.ast import flatten

result = [item.rsplit('[', 1)[0] for item in flatten(lst)]  
于 2013-05-10T16:38:17.193 回答
0

扁平化和清理词是两个独立的任务。Funcy库有函数flattenre_find来解决它们:

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

或者这可以通过其他一些功能更有效地完成:

from funcy import iflatten, re_finder
flat_list = map(re_finder(r'^\w+'), iflatten(your_list))
于 2014-06-04T16:46:04.830 回答