【问题标题】:Count from a list and appending it从列表中计数并附加它
【发布时间】:2017-05-09 11:20:42
【问题描述】:

我有一个嵌套列表,其中包含多次出现的各种名称。我需要编写一个函数来计算每个名称出现的次数,然后将其附加到一个列表中,该列表显示名称,然后是它的计数。例如,输入可能如下所示:

L = [['Jimmy', 'Henry'], ['Henry', 'Bob'], ['Lucas', 'Jimmy']]

我希望输出是这样的列表:

newList = [['Jimmy', 2], ['Henry', 2], ['Bob', 1], ['Lucas', 1]]

我写了以下函数:

def nameCount(target):
    count = 0
    name = target
    for subList in L:
        if name in subList:
            count += 1
    print(count)

但是,这只会产生我必须指定为目标的一个名称的数量。我希望它遍历每个名​​称并计算它存在的次数,然后将其附加到新列表中。

【问题讨论】:

  • collections.Counter(itertools.chain(*L)) 似乎是最简单的方法。

标签: python list count


【解决方案1】:

使用collections.Counter:

from collections import Counter

print Counter(i for x in L for i in x).most_common()
# [('Jimmy', 2), ('Henry', 2), ('Bob', 1), ('Lucas', 1)]

您还可以使用带有 for 循环的 vanilla dict:

d = {}
for x, y in L:
   d[x] = d.get(x, 0) + 1
   d[y] = d.get(y, 0) + 1

print d.items()
# [('Jimmy', 2), ('Henry', 2), ('Bob', 1), ('Lucas', 1)]

【讨论】:

  • 任务说我不能使用任何内置函数。
  • 您在d[y] = d.get(x, 0) + 1 中有错字,应该是d[y] = d.get(y, 0) + 1。而且您的解决方案与两个元素绑定L
【解决方案2】:
import collections
import itertools
L = [['Jimmy', 'Henry'], ['Henry', 'Bob'], ['Lucas', 'Jimmy']]

[list(i) for i in collections.Counter(itertools.chain(*L)).items()]

---> [['Bob', 1], ['Lucas', 1], ['Jimmy', 2], ['Henry', 2]]

【讨论】:

    【解决方案3】:

    如果你不想导入任何东西,你可以这样做:

    L = [['Jimmy', 'Henry'], ['Henry', 'Bob'], ['Lucas', 'Jimmy']]
    temp = [x for y in L for x in y]  # flattens L
    new_list = [[k, temp.count(k)] for k in set(temp)]
    print(new_list)  # [['Henry', 2], ['Lucas', 1], ['Bob', 1], ['Jimmy', 2]]
    

    请注意,它不保留顺序,因为它涉及创建集合。不需要创建temp,但确实可以加快速度。它用于展平最初嵌套的原始列表。

    【讨论】:

      【解决方案4】:

      你可以使用collections.Counter:

      >>> collections.Counter(itertools.chain(*L))
      Counter({'Bob': 1, 'Henry': 2, 'Jimmy': 2, 'Lucas': 1})
      
      >>> collections.Counter(itertools.chain(*L)).items()
      [('Bob', 1), ('Jimmy', 2), ('Lucas', 1), ('Henry', 2)]
      

      不使用任何内置函数,您可以:

      result = {}
      for subList in L:
          for name in subList:    
              result[name] = result.get(name, 0) + 1
      print(result.items())
      

      【讨论】:

        【解决方案5】:

        如果你只想使用基本对象:

        L = [['Jimmy', 'Henry'], ['Henry', 'Bob'], ['Lucas', 'Jimmy']]
        
        def nameCount(nested_names):
            count = {}
            for sub_list in nested_names:
                for name in sub_list:
                    count[name] = count.get(name, 0) + 1
            print(count)
        
        nameCount(L)
        

        它输出:

        {'Bob': 1, 'Jimmy': 2, 'Lucas': 1, 'Henry': 2}
        

        如果你想要排序的元组:

        print(sorted(count.items(), key=lambda x: x[1], reverse=True))
        

        哪个输出:

        # [('Jimmy', 2), ('Henry', 2), ('Bob', 1), ('Lucas', 1)]
        

        【讨论】:

        • sorted() 当然是内置的(虽然我不喜欢没有更多细节的这种任意要求)
        • 反对者:欢迎提出建设性的批评。我的答案是dict.get 的第一个答案,比@Moses Koledoye 的答案早一分钟。它也是第一个没有任何import 的高效。
        【解决方案6】:

        如果您想使用 numpy,以下将返回元组:

        import numpy as np
        L = [['Jimmy', 'Henry'], ['Henry', 'Bob'], ['Lucas', 'Jimmy']]
        name, count = np.unique(L, return_counts=True)
        zip(name, count)
        

        以下也将返回一个字典:

        dict(zip(name,count))
        

        【讨论】:

          【解决方案7】:

          你为什么不使用字典?我会这样做:

          def names_count(L):
              result = {}
          
              for subList in L:
                  for name in subList:
                      if name not in dict:
                          result[name] = 0
                      result[name] = result[name] + 1
          
              return(result)
          

          如果您必须使用结果列表来执行此操作,则可以使用以下解决方法:

          def get_index_of_list_with(list, name):
              for i in len(list): # I normally prefered enumerate here but you didn't want anything but pure iteration, right?
                  if list[i] is name:
                      return i
              list.append[name, 0]
              return len(list) - 1
          
          
          def nameCount(L):
              result = []
          
              for subList in L:
                  for name in subList:
                      index = get_index_of_list_with(result, name)
                      result[index] = result[index] + 1
              print(result)
          

          请注意,第二个解决方案根本不是 Pythonic,而且可能还有更好的方法来编写第一个示例。它们只是草稿。

          【讨论】:

            猜你喜欢
            • 2018-01-08
            • 2016-07-08
            • 2021-09-27
            • 1970-01-01
            • 1970-01-01
            • 2020-09-05
            • 1970-01-01
            • 1970-01-01
            • 2020-09-05
            相关资源
            最近更新 更多