【问题标题】:Python count lists in list列表中的 Python 计数列表
【发布时间】:2016-12-24 23:07:05
【问题描述】:

我有以下清单:

data = [('A', 'B'), ('C','D'), ('E','F'), ('G','H'), ('B','A'), ('D','C')]

第一个和第二个元素的顺序无关紧要,例如,('A', 'B') 和 ('B','A') 被视为相同。期望的结果是:

('A','B') 2
('C','D') 2
('E','F') 1
('G','H') 1

我试过这个(改编自How to count number of duplicates in a list of tuples?):

data = [('A', 'B'), ('C','D'), ('E','F'), ('G','H'), ('B','A'), ('D','C')]
from collections import Counter 
for i, j in Counter(data).most_common():
    print i, j

结果如下:

('G', 'H') 1
('B', 'A') 1
('E', 'F') 1
('A', 'B') 1
('D', 'C') 1
('C', 'D') 1

有什么建议吗?

【问题讨论】:

  • 每个元组中是否总是只有两个项目?
  • 是的。每个元组中有两个项目。
  • 参见例如stackoverflow.com/q/41259493/3001761,您可以调整它以与计数器一起使用。或者只是map(frozenset, data)
  • 统计每个列表中字母出现的次数作为中间步骤。

标签: python


【解决方案1】:

解决此问题的一种方法是遍历每个元组并使用sorted() 按字母顺序排列它们。因此("B", "A") 将变为("A", "B") 等。然后您可以继续使用您之前编写的代码来计算出现次数

from collections import Counter

data = [('A', 'B'), ('C','D'), ('E','F'), ('G','H'), ('B','A'), ('D','C')]

data = [tuple(sorted(item)) for item in data]  # sorts each tuple alphabetically

for i, j in Counter(data).most_common():
    print(i, j)

或者不使用列表解析(并使用 Python 2.x 语法):

from collections import Counter

data = [('A', 'B'), ('C','D'), ('E','F'), ('G','H'), ('B','A'), ('D','C')]

for i in range(0, len(data)):
    data[i] = tuple(sorted(data[i]))

for i, j in Counter(data).most_common():
    print i, j

【讨论】:

    【解决方案2】:

    一种方法是计算内部元组的计数器,如下所示:

    from collections import Counter
    data = [('A', 'B'), ('C','D'), ('E','F'), ('G','H'), ('B','A'), ('D','C')]
    data = [Counter(x) for x in data]
    print Counter([", ".join(list(x.elements())) for x in data]).most_common()
    

    【讨论】:

      【解决方案3】:

      tuple 不是您用例的最佳类型。考虑改用set

      例如,

      (1, 2) == (2, 1)    # False
      {1, 2} == {2, 1}    # True
      

      【讨论】:

        【解决方案4】:

        不加载Counter模块的简单解决方案:

        data = [('A', 'B'), ('C','D'), ('E','F'), ('G','H'), ('B','A'), ('D','C')]
        counts = {}
        for t in data:
            k = tuple(sorted(t))
            counts[k] = counts.get(k, 0) + 1
        
        print(counts)
        

        输出:

        {('C', 'D'): 2, ('G', 'H'): 1, ('E', 'F'): 1, ('A', 'B'): 2}
        

        【讨论】:

          【解决方案5】:

          尝试使用熊猫。 :)

          import pandas as pd
          pd.Series(pd.Series([('a','b'),('b','a'),('c','d')]).apply(lambda x: tuple(sorted(list(x))))).value_counts()
          
          #output
          (a, b)    2
          (c, d)    1
          dtype: int64
          

          【讨论】:

            【解决方案6】:

            如果由于某种原因你不想使用 Counter

            data_dict = {}
            for d in data:
                temp_d = tuple(sorted(d))
                if temp_d in data_dict:
                    data_dict[temp_d] += 1
                else:
                    data_dict[temp_d] = 1
            

            输出

            {('A', 'B'): 2, ('C', 'D'): 2, ('E', 'F'): 1, ('G', 'H'): 1}
            

            如果你使用熊猫

            import pandas as pd
            pd.Series(data).map(lambda x: tuple(sorted(x))).value_counts()
            

            输出

            (C, D)    2
            (A, B)    2
            (G, H)    1
            (E, F)    1
            dtype: int64
            

            【讨论】:

              【解决方案7】:

              您必须在计数之前对其进行排序。

              data = [('A', 'B'), ('C','D'), ('E','F'), ('G','H'), ('B','A'), ('D','C')]
              
              def count():
                  sorted_data = [tuple(sorted(d)) for d in data]
                  for i, j in Counter(sorted_data).most_common():
                      print(i, j)
              

              【讨论】:

              • 浪费计算时间的错误解决方案。
              • 我不这么认为。如果您不知道自己在寻找什么,那么谈论计算时间是可笑的。下次请看好点:提问的Kevin,最后选择了一个和我建议的完全一样的解决方案。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-03-04
              • 2017-03-08
              • 1970-01-01
              • 1970-01-01
              • 2020-11-27
              • 2021-07-16
              相关资源
              最近更新 更多