当任何一个元素与另一个列表的元素匹配时,如何从列表的列表中提取列表?

时间:2018-07-12 14:22:39

标签: python

我又被提取和比较列表元素所困扰。

我有以下列表列表:

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

谁能告诉我该怎么办?

7 个答案:

答案 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']}]