【问题标题】:Categorize a list of lists by 1 element in python在python中按1个元素对列表列表进行分类
【发布时间】:2010-01-19 09:22:43
【问题描述】:

列表示例:

[
["url","name","date","category"]
["hello","world","2010","one category"]
["foo","bar","2010","another category"]
["asdfasdf","adfasdf","2010","one category"]
["qwer","req","2010","another category"]
]

我希望做的是创建一个字典 -> 类别:[条目列表]。

结果字典将是:

{"category" : [["url","name","date","category"]],
"one category" : [["hello","world","2010","one category"],["asdfasdf","adfasdf","2010","one category"]],
"another category" : [["foo","bar","2010","another category"], ["qwer","req","2010","another category"]]}

【问题讨论】:

    标签: python list dictionary map sorting


    【解决方案1】:
    dict((category, list(l)) for category, l 
         in itertools.groupby(l, operator.itemgetter(3))
    

    这里主要是itertools.groupby的用法。它只是返回可迭代对象而不是列表,这就是为什么要调用 list(l),这意味着如果你没问题,你可以简单地写 dict(itertools.groupby(l, operator.itemgetter(3)))

    【讨论】:

    • 您可以使用 operator.itemgetter(3) 代替那个 lambda。
    • 我永远不知道这些使用 itertools/lambdas/whatnot 的 1/2 衬里是否比更详细/显式的版本更好。对于阅读本文而没有看到正在发生的事情的示例的人来说,这很难理解。
    • @Idan - 在阅读了一次 groupby 所做的之后,这非常简单。如果这两行在一个名为group_by_categories 的方法中就更好了。
    • 请注意,要使其正常工作,输入列表必须首先使用传递给groupby的相同函数进行排序。
    【解决方案2】:
    newdict = collections.defaultdict(list)
    for entry in biglist:
      newdict[entry[3]].append(entry)
    

    【讨论】:

    • newdict['category that does not exist'] 向 newdict 添加一个新元素。这对原始海报来说可能没问题,但这是一个非常具体的语义。
    • @EOL:它只选择原始列表中的类别,所以我在这里没有看到问题。
    • 一般来说,当'不存在的类别'不在biglist中时,没有理由将newdict['不存在的类别']设置为[]。例如,可以使用try: newdict['example category'] except KeyError:… 测试某些类别的存在如果 newdict 是 collections.defaultdict,则不会引发异常,而 dict 会引发异常。我只是想提出一个警告:collections.defaultdicts 的行为与 dicts 不完全相同,而原始发​​布者想要一个 dict。
    • 简而言之,你不能让它在初始化过程中表现得像一个 defaultdict,而之后又像一个 dict。
    【解决方案3】:

    ghostdog74 答案的变体,完全使用 setdefaults 的语义:

    result={}
    for li in list_of_lists:
        result.setdefault(li[-1], []).append(li)
    

    【讨论】:

      【解决方案4】:
      list_of_lists=[
      ["url","name","date","category"],
      ["hello","world","2010","one category"],
      ["foo","bar","2010","another category"],
      ["asdfasdf","adfasdf","2010","one category"],
      ["qwer","req","2010","another category"]
      ]
      d={}
      for li in list_of_lists:
          d.setdefault(li[-1], [])
          d[ li[-1] ].append(li)
      for i,j in d.iteritems():
          print i,j
      

      【讨论】:

      • +1,但请参阅我的回答,它利用了 setdefault() 返回值这一事实。
      【解决方案5】:
      
      d = {}
      for e in l:
          if e[3] in d:
              d[e[3]].append(e)
          else:
              d[e[3]] = [e]
      

      【讨论】:

      • 这有什么问题?这很简单,而且确实有效。 L[0][3] 是“类别”,依此类推。
      【解决方案6】:
      >>> l = [
      ... ["url","name","date","category"],
      ... ["hello","world","2010","one category"],
      ... ["foo","bar","2010","another category"],
      ... ["asdfasdf","adfasdf","2010","one category"],
      ... ["qwer","req","2010","another category"],
      ... ]
      #Intermediate list to generate a more dictionary oriented data
      >>> dl = [ (li[3],li[:3]) for li in l ]
      >>> dl
      [('category', ['url', 'name', 'date']), 
       ('one category', ['hello', 'world', '2010']), 
       ('another category', ['foo', 'bar', '2010']), 
       ('one category', ['asdfasdf', 'adfasdf', '2010']), 
       ('another category', ['qwer', 'req', '2010'])]
      #Final dictionary
      >>> d = {}
      >>> for cat, data in dl:
      ...   if cat in d:
      ...     d[cat] = d[cat] + [ data ]
      ...   else:
      ...     d[cat] = [ data ]
      ...
      >>> d
      {'category': [['url', 'name', 'date']], 
       'one category': [['hello', 'world', '2010'], ['asdfasdf', 'adfasdf', '2010']], 
       'another category': [['foo', 'bar', '2010'], ['qwer', 'req', '2010']]}
      

      最终数据有点不同,因为我没有将数据包含在类别中(对我来说似乎毫无意义),但如果需要,您可以轻松添加...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-07-19
        • 2019-07-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多