【问题标题】:Search a list of nested tuples of strings in python在python中搜索嵌套的字符串元组列表
【发布时间】:2013-05-05 09:25:40
【问题描述】:

假设我有一个列表 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 级嵌套。

【问题讨论】:

  • 有时越冗长的代码就越易读
  • 6 行这对我来说似乎还不错 XD
  • 告诉我们你得到了什么,我相信有人会帮助清理它
  • 嵌套是否任意深?

标签: python nested tuples flatten


【解决方案1】:

类似这样的:

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

【讨论】:

  • @Darko 不要尝试在 cmets 中发布代码,而是更新问题
【解决方案2】:

扁平化questions have been answered many times

tl;dr使用可怕的文档ast模块的扁平化功能

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

      扁平化和清理单词是两个独立的任务。 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))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-26
        • 1970-01-01
        • 2010-12-12
        • 2020-03-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多