如何根据每个子列表中的公共密钥创建一个新的子图层,以便对子列表进行分类?换句话说,如何将子列表放入列表中的新子列表中,索引1处的每个项目都相同?
例如,我想将以下的子列表列表转换为子列表列表,其中每个子列表都在新的子列表中,其中索引1处的每个项在该子列表中是相同的。我想将此列表中的苹果,香蕉和橙子的子列表放入新的子列表中。
lsta = [['2014W01','apple',21,'apple@gmail.com'],['2014W02','apple',19,'apple@g.com'],['2014W02','banana',51,'b@gmail.com'],['2014W03','apple',100,'apple@gmail.com'],['2014W01','banana',71,'b@yahoo.com'],['2014W02','organge',21,'organge@gmail.com']]
我希望将三个苹果子列表包含在一个新的子列表中,以及将两个香蕉子列表放入一个新的子列表中等。
Desired_List = [[['2014W01','apple',21,'apple@gmail.com'],['2014W02','apple',19,'apple@g.com'],['2014W03','apple',100,'apple@gmail.com']],[['2014W02','banana',51,'b@gmail.com'],['2014W01','banana',71,'b@yahoo.com']],[['2014W02','organge',21,'organge@gmail.com']]]
奖励积分,如果您可以告诉我如何进行多种分类(例如,不仅按水果类型分类,还按周分类)?
答案 0 :(得分:5)
In [43]: import itertools as IT
In [44]: import operator
In [46]: [list(grp) for key, grp in IT.groupby(sorted(lsta, key=operator.itemgetter(1)), key=operator.itemgetter(1))]
Out[46]:
[[['2014W01', 'apple', 21, 'apple@gmail.com'],
['2014W02', 'apple', 19, 'apple@g.com'],
['2014W03', 'apple', 100, 'apple@gmail.com']],
[['2014W02', 'banana', 51, 'b@gmail.com'],
['2014W01', 'banana', 71, 'b@yahoo.com']],
[['2014W02', 'organge', 21, 'organge@gmail.com']]]
答案 1 :(得分:3)
通常情况下,我会在此使用itertools.groupby
,但只是为了好玩,这是一种手动完成所有繁重工作的方法
def transform(lista):
d = {}
for subl in lista:
k = subl.pop(1)
if k not in d:
d[k] = []
d[k].append(subl)
answer = []
for k, lists in d.items():
temp = []
for l in lists:
l.insert(1, k)
temp.append(l)
answer.append(temp)
return answer
输出:
In [56]: transform(lsta)
Out[56]:
[[['2014W02', 'organge', 21, 'organge@gmail.com']],
[['2014W01', 'apple', 21, 'apple@gmail.com'],
['2014W02', 'apple', 19, 'apple@g.com'],
['2014W03', 'apple', 100, 'apple@gmail.com']],
[['2014W02', 'banana', 51, 'b@gmail.com'],
['2014W01', 'banana', 71, 'b@yahoo.com']]]
答案 2 :(得分:1)
我会采取一些不同的方法。您可能希望分组依据字段是dict
中的查找值。这个值可以是各种各样的list
..无论你想在这里调用每个子列表。我会将每个人称为FruitPerson
。
from collections import defaultdict, namedtuple
FruitPerson = namedtuple('FruitPerson','id age email')
d = defaultdict(list)
for sublist in lsta:
d[sublist[1]].append(FruitPerson(sublist[0],*sublist[2:]))
然后,例如:
d['apple']
Out[19]:
[FruitPerson(id='2014W01', age=21, email='apple@gmail.com'),
FruitPerson(id='2014W02', age=19, email='apple@g.com'),
FruitPerson(id='2014W03', age=100, email='apple@gmail.com')]
d['apple'][0]
Out[20]: FruitPerson(id='2014W01', age=21, email='apple@gmail.com')
d['apple'][0].id
Out[21]: '2014W01'
编辑:好的,多重分类奖励积分问题。你只需要嵌套你的词典。语法有点傻,因为defaultdict
的参数必须是可调用的;您可以使用lambda
或functools.partial
:
FruitPerson = namedtuple('FruitPerson','age email') #just removed 'id' field
d = defaultdict(lambda: defaultdict(list))
for sublist in lsta:
d[sublist[1]][sublist[0]].append(FruitPerson(*sublist[2:]))
d['apple']
Out[37]: defaultdict(<type 'list'>, {'2014W03': [FruitPerson(age=100, email='apple@gmail.com')], '2014W02': [FruitPerson(age=19, email='apple@g.com')], '2014W01': [FruitPerson(age=21, email='apple@gmail.com')]})
d['apple']['2014W01']
Out[38]: [FruitPerson(age=21, email='apple@gmail.com')]
d['apple']['2014W01'][0].email
Out[40]: 'apple@gmail.com'
虽然诚实地说,您应该考虑升级到可以理解SELECT whatever FROM whatever WHERE something
类型查询的真实关系数据库。