Python 如何基于每个子列表中的公共密钥创建新的子列表层,以便对子列表进行分类?

Python 如何基于每个子列表中的公共密钥创建新的子列表层,以便对子列表进行分类?,python,list,categories,sublist,Python,List,Categories,Sublist,如何基于每个子列表中的公共密钥创建新的子列表层,以便对子列表进行分类?换句话说,如果索引1中的每个项都相同,如何将子列表放置到列表中的新子列表中 例如,我想将下面的子列表转换为子列表列表,其中每个子列表都位于一个新的子列表中,其中索引1处的每个项在该子列表中都是相同的。我想把这个列表中苹果、香蕉和橙子的子列表放到一个新的子列表中 lsta = [['2014W01','apple',21,'apple@gmail.com'],['2014W02','apple',19,'apple@g.com'

如何基于每个子列表中的公共密钥创建新的子列表层,以便对子列表进行分类?换句话说,如果索引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']]]
如果您能告诉我如何进行多重分类,例如,不仅按水果类型分类,而且按周分类,则可获得额外积分

通常情况下,我会使用itertools.groupby来处理这个问题,但只是为了好玩,这里有一个方法可以手动完成所有的重物搬运

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']]]
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']]]
通常,我会使用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']]]

我会采取不同的策略。您可能希望group by字段成为dict中的查找值。该值可以是各种字段的列表。。无论您想在这里调用每个子列表。我会把每个人都称为水果人

然后,例如:

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执行此操作:


虽然在这一点上,你应该考虑到一个真正的关系数据库,它可以从任何类型的查询中选择任何东西。您可能希望group by字段成为dict中的查找值。该值可以是各种字段的列表。。无论您想在这里调用每个子列表。我会把每个人都称为水果人

然后,例如:

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执行此操作:


虽然在这一点上,你应该考虑到一个真正的关系数据库,它可以从任何类型的查询中选择任何东西。我想我应该把问题改为在这种情况下我会如何使用dicts相关的:你考虑过用dicts来代替吗?很好的建议!我想我应该把问题改为在这种情况下如何使用口述: