我又被提取和比较列表元素所困扰。
我有以下列表列表:
list = [['laravel', 1.0, 54],
['laravel', 1.0, 3615],
['php', 1.0, 1405],
['php', 1.0, 5175],
['php', 1.0, 5176],
['php', 1.0, 54],
['php', 1.0, 5252],
['php', 1.0, 5279],
['python', 1.0, 54],
['laravel', 0.8333333333333334, 54],
['python',0.8333333333333334, 3615]]
我们可以看到ID 54具有3种技能(laravel,python,php)和3615具有2种技能
现在,我的愿望输出如下:
[{
id :54
No_matched_skills: 3
skills: laravel,python,php
},
{
id : 3615
No_matched_skills : 2
skills: laravel,python
}]
谁能告诉我该怎么办?
答案 0 :(得分:1)
您可能想要这样的东西:
from itertools import groupby
from operator import itemgetter
l = [['laravel', 1.0, 54],
['laravel', 1.0, 3615],
['php', 1.0, 1405],
['php', 1.0, 5175],
['php', 1.0, 5176],
['php', 1.0, 54],
['php', 1.0, 5252],
['php', 1.0, 5279],
['python', 1.0, 54],
['laravel', 0.8333333333333334, 54],
['python',0.8333333333333334, 3615]]
o = []
for key, grp in groupby(sorted(l, key=itemgetter(2)), key=itemgetter(2)):
skills = [l[0] for l in grp]
o.append({"id": key, "no_matched_skills": len(skills), "skills": skills})
o
输出:
[{'id': 54,
'no_matched_skills': 4,
'skills': ['laravel', 'php', 'python', 'laravel']},
{'id': 1405, 'no_matched_skills': 1, 'skills': ['php']},
{'id': 3615, 'no_matched_skills': 2, 'skills': ['laravel', 'python']},
{'id': 5175, 'no_matched_skills': 1, 'skills': ['php']},
{'id': 5176, 'no_matched_skills': 1, 'skills': ['php']},
{'id': 5252, 'no_matched_skills': 1, 'skills': ['php']},
{'id': 5279, 'no_matched_skills': 1, 'skills': ['php']}]
答案 1 :(得分:1)
我将变量名从list
修改为lists
,因为尽管list
不是保留关键字,但是您将覆盖列表数据结构的关键字。
lists = [['laravel', 1.0, 54],
['laravel', 1.0, 3615],
['php', 1.0, 1405],
['php', 1.0, 5175],
['php', 1.0, 5176],
['php', 1.0, 54],
['php', 1.0, 5252],
['php', 1.0, 5279],
['python', 1.0, 54],
['laravel', 0.8333333333333334, 54],
['python',0.8333333333333334, 3615]]
skills = {}
for l in lists:
skill, _, id = l
if id in skills:
skills[id].append(skill)
else:
skills[id] = [skill]
output = []
for k in skills.keys():
output.append({
"id": k,
"No_matched_skills": len(skills[k]),
"skills": ",".join(skills[k])
})
print(output)
让我们逐行看一下:
skills = {}
创建一个新的词典,以便为lists
变量中的每个唯一ID,我们可以存储技能列表。
for l in lists:
skill, _, id = l
if id in skills:
skills[id].append(skill)
else:
skills[id] = [skill]
不确定中间变量是什么,所以我使用_
作为变量名。根据需要进行更改。
我正在使用skill, _, id = l
行将列表l
解压缩到这些变量中。
如果我在id
字典中找到了当前的skills
,我就继续使用list.append()
将其添加到现有列表中。否则,我将使用当前技能在适当的位置创建新列表。
output = []
for k in skills.keys():
output.append({
"id": k,
"No_matched_skills": len(skills[k]),
"skills": ",".join(skills[k])
})
对于skills
词典中的每个键,我将一个词典附加到output
列表中。 id
只是键,No_matched_skills
是该键的列表大小,我使用",".join(skills[k])
来获取该列表并将其另存为逗号分隔的字符串。>
答案 2 :(得分:1)
from collections import defaultdict as dd
d = dd(set)
skillList = [['laravel', 1.0, 54],
['laravel', 1.0, 3615],
['php', 1.0, 1405],
['php', 1.0, 5175],
['php', 1.0, 5176],
['php', 1.0, 54],
['php', 1.0, 5252],
['php', 1.0, 5279],
['python', 1.0, 54],
['laravel', 0.8333333333333334, 54],
['python',0.8333333333333334, 3615]]
for i in skillList:
d[i[2]].add(i[0])
temp = [ {'id':i,'No_matched_skills':len(d[i]),'skills':','.join(d[i])} for i in d if len(d[i])>1]
print temp
这将删除重复项,仅显示具有一项以上技能的重复项
输出:
[{'skills': 'laravel,python,php', 'No_matched_skills': 3, 'id': 54},
{'skills': 'laravel,python', 'No_matched_skills': 2, 'id': 3615}]
答案 3 :(得分:1)
在Python中使用“ Counter
”和“ defaultdict
”:
l = [['laravel', 1.0, 54],
['laravel', 1.0, 3615],
['php', 1.0, 1405],
['php', 1.0, 5175],
['php', 1.0, 5176],
['php', 1.0, 54],
['php', 1.0, 5252],
['php', 1.0, 5279],
['python', 1.0, 54],
['laravel', 0.8333333333333334, 54],
['python',0.8333333333333334, 3615]]
from pprint import pprint
from collections import Counter, defaultdict
c = Counter(i[2] for i in l)
d = defaultdict(lambda: defaultdict(int))
for i in l:
if c[i[2]] > 1:
d[i[2]][i[0]] += 1
rv = []
for k, v in d.items():
rv.append({'id': k, 'No_matched_skills': len(v), 'skills': [*v]})
pprint(rv, width=10)
输出:
[{'No_matched_skills': 3,
'id': 54,
'skills': ['laravel',
'php',
'python']},
{'No_matched_skills': 2,
'id': 3615,
'skills': ['laravel',
'python']}]
答案 4 :(得分:0)
您可以使用类似的东西
my_list = [['laravel', 1.0, 54],
['laravel', 1.0, 3615],
['php', 1.0, 1405],
['php', 1.0, 5175],
['php', 1.0, 5176],
['php', 1.0, 54],
['php', 1.0, 5252],
['php', 1.0, 5279],
['python', 1.0, 54],
['laravel', 0.8333333333333334, 54],
['python',0.8333333333333334, 3615]]
compute_dict = {}
for l in my_list:
compute_dict.setdefault(l[2], [])
compute_dict[l[2]].append(l[0])
final_list = []
for k,v in compute_dict.items():
final_list.append({"id":k,"No_matched_skills":len(set(v)),"skills":", ".join(set(v))})
基本上,第一步是创建一个ID为键,编程语言为值的字典。因此,compute_dict
看起来像
>>> {54: ['laravel', 'php', 'python', 'laravel'], 3615: ['laravel','python'], 1405: ['php'], 5175: ['php'], 5176: ['php'], 5252: ['php'], 5279: ['php']}
因此,从那里可以创建具有预期输出的列表。请注意,我正在使用set()
以便从原始字典中删除重复项。
答案 5 :(得分:0)
如果您对使用第3方库感到满意,可以使用Pandas。给定一个列表L
:
import pandas as pd
# construct dataframe from list
df = pd.DataFrame(L, columns=['skills', 'value', 'id'])
# define aggregation functions
funcs = {'No_matched_skills': 'nunique', 'skills': lambda x: ', '.join(x.unique())}
# apply groupby and convert to dictionary
res = df.groupby('id', as_index=False)['skills'].agg(funcs).to_dict('records')
print(res)
[{'No_matched_skills': 3, 'id': 54, 'skills': 'laravel, php, python'},
{'No_matched_skills': 1, 'id': 1405, 'skills': 'php'},
{'No_matched_skills': 2, 'id': 3615, 'skills': 'laravel, python'},
{'No_matched_skills': 1, 'id': 5175, 'skills': 'php'},
{'No_matched_skills': 1, 'id': 5176, 'skills': 'php'},
{'No_matched_skills': 1, 'id': 5252, 'skills': 'php'},
{'No_matched_skills': 1, 'id': 5279, 'skills': 'php'}]
答案 6 :(得分:0)
您可以使用itertools.groupby
:
import itertools
_list = [['laravel', 1.0, 54], ['laravel', 1.0, 3615], ['php', 1.0, 1405], ['php', 1.0, 5175], ['php', 1.0, 5176], ['php', 1.0, 54], ['php', 1.0, 5252], ['php', 1.0, 5279], ['python', 1.0, 54], ['laravel', 0.8333333333333334, 54], ['python', 0.8333333333333334, 3615]]
new_list = [[a, list(b)] for a, b in itertools.groupby(sorted(_list, key=lambda x:x[-1]), key=lambda x:x[-1])]
final_result = [{'id':a, 'No_matched_skills':len(b), 'skills':[c for c, *_ in b]} for a, b in new_list]
filtered = list(filter(lambda x:x['No_matched_skills'] > 1, final_result))
输出:
[{'id': 54, 'No_matched_skills': 4, 'skills': ['laravel', 'php', 'python', 'laravel']}, {'id': 3615, 'No_matched_skills': 2, 'skills': ['laravel', 'python']}]