社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

python-嵌套列表结构中的聚合数据

Lou_Ds • 5 年前 • 1482 次点击  

我有一个嵌套子列表的列表,其结构如下

in_data = 
 [
   [
     ['name', 'name_1'],  
     ['item_B', '2'], 
     ['item_C', '3'], 
     ['item_D', '4']
   ],
   [
     ['name', 'name_2'], 
     ['item_B', '5'], 
     ['item_A', '2']
   ],
   [
     ['name', 'name_3'], 
     ['item_B', '6'], 
     ['item_C', '7']
   ]
]

我正在收集所有的数据 in_data 做一个 唯一列表 包含子列表的 “标题” / 姓名 每个项目一个+正确顺序的值。 因此,信息被保存在不同的数据结构中。

我想达到这个目标 :

res_list = 
[
  ['name', ' name_1', ' name_2', 'name_3'], 
  ['item_B', '2', '5', '6'], 
  ['item_C', '3','-', '7'], 
  ['item_D', '4','-', '-'], 
  ['item_A', '-','2', '-'] 
]

我正试着用最恶毒的方式做这件事。我尝试了for循环,也尝试了map()+lambda,但没有成功。

更新

这是我的完整代码。

def get_names(a):
    return reduce(lambda ac, v: ac + [v[0]] if v[0] not in ac else ac, a, [])[1:]


def collect_all_data(_data):
    all_names = set(reduce(lambda x,y: x+y, map(get_names, _data)))
    unique_names = list(map(lambda x: [x], all_names))
    agg = list(map(lambda x:[x], unique_names))
    agg = [['names']] + unique_names
    for team_i, team_data in enumerate(_data):
        team = ""
        for i, skill_val in enumerate(team_data):
            if i==0:
                team = skill_val[1] 
                agg[0].append(team)
                continue
            else :
                 for i_us,us in enumerate(unique_names):
                     if us[0] == skill_val[0]:
                         agg[i_us+1].append(skill_val[1])

    print("\--->{} type:{}".format(agg, type(agg)))
    return agg

collect_all_data(in_data)

它产生输出:

注意 :的 秩序 子列表的 不重要,除非 这个 第一个 ['name', ' name_1', ' name_2', 'name_3'] 这应该是第一次。

  [
    ['names', 'name_1', 'name_2', 'name_3'], 
    ['item_D', '4'], 
    ['item_B', '2', '5', '6'], 
    ['item_C', '3', '7'], 
    ['item_A', '2']
  ]

代码太长,但它没有添加 '-' 当物品没有价值的时候。 会是简单的方法吗?

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/49407
 
1482 次点击  
文章 [ 2 ]  |  最新文章 5 年前
RomanPerekhrest
Reply   •   1 楼
RomanPerekhrest    5 年前

优化的方法(由复合dict键提供支持 (<skill name>, <column name>) dict.get 方法):

header = ['names']
names = set()
d = {}

for lst in in_data:
    col_name = lst[0][-1]
    header.append(col_name)
    for name, val in lst[1:]:
        names.add(name)
        d[name, col_name] = val

res = [[n, *[d.get((n, h), '-') for h in header[1:]]] for n in names]
res.insert(0, header)
print(res)

输出:

[['names', 'name_1', 'name_2', 'name_3'],
 ['item_C', '3', '-', '7'],
 ['item_D', '4', '-', '-'],
 ['item_B', '2', '5', '6'],
 ['item_A', '-', '2', '-']]
Ajax1234
Reply   •   2 楼
Ajax1234    5 年前

你可以用 collections.defaultdict :

import collections
in_data = [[['name', 'name_1'], ['item_B', '2'], ['item_C', '3'], ['item_D', '4']], [['Skill', 'name_2'], ['item_B', '5'], ['item_A', '2']], [['Skill', 'name_3'], ['item_B', '6'], ['item_C', '7']]]
d = [list(zip(['name', *b[0][1:]], i)) for b in in_data for i in b[1:]]
new_d = collections.defaultdict(dict)
for i in d:
   new_d[dict(i)['name']][i[-1][0]] = i[-1][-1]

all_names = list({i for b in new_d.values() for i in b})[::-1]
result = [['name', *all_names], *[[a, *[b.get(k, '-') for k in all_names]] for a, b in new_d.items()]]

输出:

[['name', 'name_1', 'name_2', 'name_3'], 
 ['item_B', '2', '5', '6'], 
 ['item_C', '3', '-', '7'], 
 ['item_D', '4', '-', '-'], 
 ['item_A', '-', '2', '-']]