【问题标题】:Python group two listsPython 分组两个列表
【发布时间】:2016-08-11 16:34:31
【问题描述】:

我有两个列表:

             A = ['T', 'D', 'Q', 'D', 'D']
             sessionid = [1, 1, 1, 2, 2]

我是否可以将 A 中的项目分组为相同的 sessionid,以便我可以打印出以下内容:

              1: ["T", "D","Q"]
              2: ["D","D"]

【问题讨论】:

  • 你听说过itertools.groupby吗?

标签: python list python-2.7 python-3.x


【解决方案1】:

itertools groupby 函数就是设计来做这种事情的。这里的其他一些答案创建了一个字典,这是非常明智的,但如果您实际上并不想要 dict,那么您可以这样做:

from itertools import groupby
from operator import itemgetter

A = ['T', 'D', 'Q', 'D', 'D']
sessionid = [1, 1, 1, 2, 2]    

for k, g in groupby(zip(sessionid, A), itemgetter(0)):
    print('{}: {}'.format(k, list(list(zip(*g))[1])))

输出

1: ['T', 'D', 'Q']
2: ['D', 'D']

operator.itemgetter(0) 返回一个可调用对象,该可调用对象从您传递的任何对象的索引 0 处获取项目; groupby 使用它作为关键函数来确定哪些项目可以组合在一起。

请注意,此解决方案和类似解决方案假定 sessionid 索引已排序。如果不是,那么您需要使用相同的键函数对zip(sessionid, A) 返回的元组列表进行排序,然后再将它们传递给groupby


编辑以在 Python 2 和 Python 3 上正常工作

【讨论】:

  • 感谢代码,因为我真的不想要 dict。只是测试你的代码,它说“'zip'对象不可下标”,你知道会发生什么吗?我在 jupyter notebook 上使用 Python 3
  • 实际上它在括号中打印出结果(“T”,“D”),我有没有机会在括号中打印出结果(例如:[“T”,“D”])?谢谢!!!!!!
【解决方案2】:

不使用itertools,可以使用字典:

index = 0
dict = {}
for i in sessionid:
    if not (i in dict):
        dict[i] = []
    else:
        dict[i].append(A[index])
    index += 1

print(dict) # {1: ['T', 'D', 'Q'], 2: ['D', 'D']}

并基于以下评论:

from collections import defaultdict
dict = defaultdict(list)
for i, item in enumerate(sessionid):
    dict[item].append(A[i])

【讨论】:

  • 您可以使用collections.defaultdict 来避免条件检查。
  • 您可以使用 enumerate 来避免自己增加索引。
  • 这会覆盖关键字并包括不必要的检查。 defaultdict 可以避免这种情况。
  • 呃! enumerate 根本没有必要。使用拉链。请参阅 Farhan 的解决方案。
【解决方案3】:

你可以使用字典和zip:

A = ['T', 'D', 'Q', 'D', 'D']
sessionid = [1, 1, 1, 2, 2]

result = {i:[] for i in sessionid}
for i,j in zip(sessionid,A):
    result[i].append(j)

或者你可以使用defaultdict:

from collections import defaultdict
result = defaultdict(list)
for k, v in zip(sessionid, A):
   result[k].append(v)

输出:

>>> result
{1: ['T', 'D', 'Q'], 2: ['D', 'D']}

【讨论】:

    【解决方案4】:

    一个班轮

    {k: list(i for (i, _) in v) for k, v in itertools.groupby(zip(A, sessionid), operator.itemgetter(1))}
    

    没有嵌套循环

    {k: list(map(operator.itemgetter(0), v)) for k, v in itertools.groupby(zip(A, sessionid), operator.itemgetter(1))}
    

    【讨论】:

    • 你还是需要导入itertools :)
    • 一行但嵌套循环。
    【解决方案5】:

    你可以这样做:

    import pandas as pd
    
    A = ['T', 'D', 'Q', 'D', 'D']
    sessionid = [1, 1, 1, 2, 2]
    
    pd.DataFrame({'A':A, 'id':sessionid}).groupby('id')['A'].apply(list).to_dict()
    
    #Out[10]: {1: ['T', 'D', 'Q'], 2: ['D', 'D']}
    

    【讨论】:

      【解决方案6】:

      您还可以将它们转换为 numpy 数组,并使用 np.where 所需的会话 ID 的索引

      import numpy as np
      
      A = np.asarray(['T', 'D', 'Q', 'D', 'D'])
      sessionid = np.asarray([1, 1, 1, 2, 2])
      
      Ind_1 = np.where(sessionid == 1)
      Ind_2 = np.where(sessionid == 2)
      
      print A[Ind_1]
      

      应该返回['T' 'D' 'Q']

      你当然可以把它变成一个函数,它接受 N、所需的会话并返回你的 A 值。

      希望这会有所帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-03
        • 2017-09-04
        • 2019-03-04
        相关资源
        最近更新 更多