【问题标题】:Nested list manipulation嵌套列表操作
【发布时间】:2019-11-28 12:11:04
【问题描述】:

我有一个嵌套列表,其中包含产品名称、产品 ID 和产品数据(另一个列表)。我想创建一个具有唯一名称和产品 ID 的字典列表,并加入与 name 和 id 变量相关的数据列表。

我的数据如下:

print(x)
[(14, 'netflix', [1, 2, 3, 4, 5, 6]), (14, 'netflix', [7, 8, 9, 10]),(15,'tv',
[1, 2, 3, 4, 5]), (15, 'tv', [7, 8, 9]), (16, 'radio', [1, 2, 3, 4]), 
(16, 'radio', [1, 2, 3, 4]) 

我想将我的数据转换为:

x = [{'product_id':x[0], 'product': row[1], 'values':row[2]} for row in x]

#or for this example

x = [{'product_id':14, 'product':'netflix', 'values':[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}, 
     {'product_id':15, 'product': 'tv',     'values':[1, 2, 3, 4, 5, 6, 7, 8, 9]}, 
     {'product_id':16, 'product': 'radio',  'values':[1, 2, 3, 4, 1, 2, 3, 4]}]

我知道我可以使用以下方法遍历嵌套列表:

for inner_l in x:
    for item in x:
        print(item)

但我不确定如何操作这些列表来创建我想要的输出

【问题讨论】:

    标签: python python-3.x pandas list numpy


    【解决方案1】:

    一种方法是使用itertools.groupby 将内部元组按第一项分组,即product_id(如果它们没有排序,则可能需要排序,并作为字典附加到列表中最后一个位置:

    from itertools import groupby
    from operator import itemgetter as ig
    
    keys = ['product_id', 'product', 'values']   
    out = []
    
    for _, ((*a,b), (*_,c)) in groupby(sorted(l, key=ig(0)), key=ig(0)):
        out.append(dict(zip(keys, a + [b+c])))
    

    print(out)
    
    [{'product': 'netflix', 'product_id': 14, 'values': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]},
     {'product': 'tv', 'product_id': 15, 'values': [1, 2, 3, 4, 5, 7, 8, 9]},
     {'product': 'radio', 'product_id': 16, 'values': [1, 2, 3, 4, 1, 2, 3, 4]}]
    

    【讨论】:

    • 帮助我完成了 99% 的工作!!谢谢!输出值应该只是一个列表,即删除方括号。
    • 但他们是,不是吗? @WilliamGoodwin 您的意思是值中的列表对吗?
    • 差不多,但对于“netflix”,例如我有 data = '[1, 2, 3, 4, 5, 6][7, 8, 9, 10]' 我正在寻找 ' [1、2、3、4、5、6、7、8、9、10]'
    • 我得到了正确的输出@WilliamGoodwin 尝试更新
    【解决方案2】:

    我的问题的一个更简单的解决方案是使用.setdefalut() 设置字典键并加入字符串:

    new_dict = dict()
    
    for i in x:
        new_dict.setdefault(i[0], '')
        new_dict[x[0]] += ',' + i[1][1:-1]
    
    for prod in new_dict:
        new_dict[prod] = new_dict[prod][1:]
    

    【讨论】:

      【解决方案3】:

      您可以这样使用defaultdict,其中x 是输入数据:

      from collections import defaultdict
      
      res = defaultdict(dict)
      
      for h in x:
        k = h[1]
        res[k]['id'] = h[0]
        res[k]['product'] = h[1]
        if 'values' in res[k]:
          res[k]['values'] += h[2]
        else:
          res[k]['values'] = h[2]
      

      然后你可以从res提取:

      print(dict(res))
      #=> {'netflix': {'id': 14, 'product': 'netflix', 'values': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}, 'tv': {'id': 15, 'product': 'tv', 'values': [1, 2, 3, 4, 5, 7, 8, 9]}, 'radio': {'id': 16, 'product': 'radio', 'values': [1, 2, 3, 4, 1, 2, 3, 4]}}
      
      print(list(res.values()))
      #=> [{'id': 14, 'product': 'netflix', 'values': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}, {'id': 15, 'product': 'tv', 'values': [1, 2, 3, 4, 5, 7, 8, 9]}, {'id': 16, 'product': 'radio', 'values': [1, 2, 3, 4, 1, 2, 3, 4]}]
      


      或嵌套的defaultdict
      res = defaultdict(lambda: defaultdict(dict, {'product': None, 'id': None, 'values': []}))
      
      for h in x:
        k = h[1]
        res[k]['id'] = h[0]
        res[k]['product'] = h[1]
        res[k]['values'] += h[2]
      

      结果:

      print(list(res.values()))
      #=> [defaultdict(<class 'dict'>, {'product': 'netflix', 'id': 14, 'values': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 7, 8, 9, 10]}), defaultdict(<class 'dict'>, {'product': 'tv', 'id': 15, 'values': [1, 2, 3, 4, 5, 7, 8, 9, 7, 8, 9]}), defaultdict(<class 'dict'>, {'product': 'radio', 'id': 16, 'values': [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]})]
      
      print([ dict(val) for val in res.values()])
      #=> [{'product': 'netflix', 'id': 14, 'values': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 7, 8, 9, 10]}, {'product': 'tv', 'id': 15, 'values': [1, 2, 3, 4, 5, 7, 8, 9, 7, 8, 9]}, {'product': 'radio', 'id': 16, 'values': [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]}]
      

      【讨论】:

        【解决方案4】:

        由于您标记了pandas,请使用pd.DataFrame 构造函数和列命名,然后使用groupbysum,并使用to_dictorient='records' 转换为字典:

        import pandas as pd
        
        x = [(14, 'netflix', [1, 2, 3, 4, 5, 6]), (14, 'netflix', [7, 8, 9, 10]),(15,'tv',
        [1, 2, 3, 4, 5]), (15, 'tv', [7, 8, 9]), (16, 'radio', [1, 2, 3, 4]), 
        (16, 'radio', [1, 2, 3, 4])]
        
        df = pd.DataFrame(x, columns=['product_id','product', 'values'])
        
        df.groupby(['product_id','product'], as_index=False)[['values']]\
          .sum()\
          .to_dict(orient='records')
        

        输出:

        [{'product_id': 14,
          'product': 'netflix',
          'values': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]},
         {'product_id': 15, 'product': 'tv', 'values': [1, 2, 3, 4, 5, 7, 8, 9]},
         {'product_id': 16, 'product': 'radio', 'values': [1, 2, 3, 4, 1, 2, 3, 4]}]
        

        【讨论】:

        • groupby('product_id') :) 我之前犯过同样的错误
        【解决方案5】:

        使用简单的迭代。

        例如:

        data = [(14, 'netflix', [1, 2, 3, 4, 5, 6]), (14, 'netflix', [7, 8, 9, 10]),(15,'tv',[1, 2, 3, 4, 5]), (15, 'tv', [7, 8, 9]), (16, 'radio', [1, 2, 3, 4]),(16, 'radio', [1, 2, 3, 4]) ]
        keys = ['product_id', 'product', 'values']
        result = {}   
        for product_id, product, values in data:
            if product_id not in result:
                result[product_id] = dict(zip(keys, (product_id, product, values)))
            else:
                result[product_id]["values"].extend(values)
        print(list(result.values()))
        

        输出:

        [{'product': 'netflix',
          'product_id': 14,
          'values': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]},
         {'product': 'tv', 'product_id': 15, 'values': [1, 2, 3, 4, 5, 7, 8, 9]},
         {'product': 'radio', 'product_id': 16, 'values': [1, 2, 3, 4, 1, 2, 3, 4]}]  
        

        【讨论】:

        • 不完全是我想要的,我想加入所有的价值列表。请参阅上面的示例输出。谢谢
        • @WilliamGoodwin。抱歉错过了。更新了 sn-p
        猜你喜欢
        • 1970-01-01
        • 2019-12-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-28
        • 1970-01-01
        • 2018-10-18
        • 2020-12-09
        相关资源
        最近更新 更多