【问题标题】:How to classify data to get a tree-like structure如何对数据进行分类以获得树状结构
【发布时间】:2020-02-21 14:29:28
【问题描述】:

我正在尝试显示有关应用程序及其数据源的信息。 我想知道如何从我的实际线路中获得这种类型的输出。

这是我的原始数据,有从 bash 获得的带有子进程的行,可以修改输出,因为子进程命令是 find、grep 和 cut 的组合。

Company1/application1 datasource=ds1
Company1/application1 datasource=ds2
Company1/application1 datasource=ds3
Company1/application2 datasource=ds1
Company1/application2 datasource=ds2
Company2/application1 datasource=ds1
Company2/application1 datasource=ds2
Company2/application2 datasource=ds1
Company2/application2 datasource=ds2
Company2/application2 datasource=ds3

我想要的输出是:

Company1
    application1 
        datasource=ds1
        datasource=ds2
        datasource=ds3
    application2 
        datasource=ds1
        datasource=ds2

Company2
    application1
        datasource=ds1
        datasource=ds2
    application2 
        datasource=ds1
        datasource=ds2
        datasource=ds3

编辑有没有办法通过列表来获得这个输出? googleit 有什么概念吗?我不知道如何开始

谢谢大家

【问题讨论】:

    标签: python string data-structures


    【解决方案1】:

    collections.defaultdict 动态创建缺失值。我认为它非常适合您的用例。

    由于您的数据集是 dictlistdict,因此我使用了 defaultdict(lambda: defaultdict(list))。其余的都是微不足道的

    from collections import defaultdict
    
    s = '''Company1/application1 datasource=ds1
    Company1/application1 datasource=ds2
    Company1/application1 datasource=ds3
    Company1/application2 datasource=ds1
    Company1/application2 datasource=ds2
    Company2/application1 datasource=ds1
    Company2/application1 datasource=ds2
    Company2/application2 datasource=ds1
    Company2/application2 datasource=ds2
    Company2/application2 datasource=ds3'''
    
    companies = defaultdict(lambda: defaultdict(list))
    
    for line in s.splitlines():
        co_app, ds = line.split(' ')
        co, app = co_app.split('/')
        companies[co][app].append(ds)
    
    for co, applications in companies.items():
        print(co)
        for app, datasets in applications.items():
            print(f'\t{app}')
            for ds in datasets:
                print(f'\t\t{ds}')
    

    【讨论】:

      【解决方案2】:

      这是一个文本文件,还是您可以选择将输出放在文本文件中?如果是这样,您可以打开文件,遍历它的行,然后继续将每一行视为您将拆分的字符串。

      伪代码:

      fi = open('myfile.txt', 'r')
      for line in fi:
          comp_application,datasource = line.split(' ')
          comp,application = comp_application.split('/')
      

      然后,您可以将这些放入字典中,如下所示:

      {'company1': {'application1': ['ds1', 'ds2']}}
      

      根据流程的其余部分,您可以使用 pretty print 之类的内容来输出您解释的代码。

      【讨论】:

        【解决方案3】:

        这里的关键是使用树。 您可以使用这样的课程非常简单地做到这一点:

        class Node:
            def __init__(self,d):
                self.children = dict()
                self.depth = d
        
            def add(self,name):
                self.children[name] = Node(self.depth+1)
        

        这里,每个节点都是一个对象,带有一个深度变量和一个包含所有子节点的字典

        首先,您必须将数据表示为一个干净的行列表,仅用空格分隔

        data = [
            "Company1 application1 datasource=ds1",
            "Company1 application1 datasource=ds2",
            "Company1 application1 datasource=ds3",
            "Company1 application2 datasource=ds1",
            "Company1 application2 datasource=ds2",
            "Company2 application1 datasource=ds1",
            "Company2 application1 datasource=ds2",
            "Company2 application2 datasource=ds1",
            "Company2 application2 datasource=ds2",
            "Company2 application2 datasource=ds3",
        ]
        

        现在,使用一点递归,你可以轻松地对数据进行排序:

        def insert(t,branch):
            if len(branch):
                if branch[0] not in t.children:
                    t.add(branch[0])
                insert(t.children[branch[0]],branch[1:])
        
        
        t = Node(0)
        
        for line in data:
            insert(t,line.split())
        
        
        def display(t):
            if t.children:
                for c in t.children:
                    print("\t" * t.depth + c)
                    display(t.children[c])
        
        
        display(t)
        

        输出:

        Company1
            application1
                datasource=ds1
                datasource=ds2
                datasource=ds3
            application2
                datasource=ds1
                datasource=ds2
        Company2
            application1
                datasource=ds1
                datasource=ds2
            application2
                datasource=ds1
                datasource=ds2
                datasource=ds3
        

        此方法的优点是您可以使用任意数量的参数。在这里,您拥有三个(公司、应用程序和数据源),但您可以拥有更多...

        希望我的代码对你有帮助!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多