【问题标题】:How to Count Total Duplicates in List and Sort Them By Name如何计算列表中的总重复项并按名称对其进行排序
【发布时间】:2018-10-07 20:34:19
【问题描述】:

我希望计算列表中重复项的总数。然后以字母/数字顺序显示列表项的名称以及重复项的数量。

例如:

-- 列表
lst = [蓝、绿、绿、黄、黄、黄、橙、橙、银、银、银、银]

-- 按 X 计算重复次数

-- 打印列表项和按排序列表名称顺序输出的总出现次数

颜色:蓝色,总数:1
颜色:绿色,总数:2
颜色:橙色,总数:2
颜色:银色,总数:4
颜色:黄色,总数:3

我可以使用字典完成上述操作,并将列表转换为集合。我的目标是使用 Python 3 的内置函数在列表类型中完成这项任务。

【问题讨论】:

  • 目前,我正在尝试尽可能充分地利用 Python,而不需要导入模块/库。这项任务更多的是一种学习体验,而不是我如何以最快/最有效的方式解决这个问题。
  • 你能edit your question 包括你最近的尝试吗?良好的“学习体验”包括尝试、犯错误和了解如何解决错误。
  • 您为什么要尝试仅使用列表来完成此操作?
  • 这是一个专注于利用列表理解的练习。据我了解,列表具有最大的灵活性,即可变结构。我可以使用集合和字典发布我的示例,但是已经有几个线程提供了非常有用的示例。我觉得我的代码会混淆我的帖子的目标,所以我省略了它们。当您有机会查看 Slider 的第二个示例时。这正是我想要实现的目标,但在许多额外的方法和模块中迷失了方向,而不是在非常基本的层面上解决问题。

标签: python python-3.x


【解决方案1】:

您可以将Countermost_common 一起使用:

from collections import Counter

lst = ['blue', 'green', 'green', 'yellow', 'yellow', 'yellow', 'orange', 'orange', 'silver', 'silver', 'silver', 'silver']
freq = Counter(lst)

现在让我们按名称排序:

print(sorted(freq.most_common(), key=lambda x: x[0])) # [('blue', 1), ('green', 2), ('orange', 2), ('silver', 4), ('yellow', 3)]

更新

如果没有字典或计数器对象,“手动”的方法是先按字母顺序对列表进行排序,然后在迭代时计算计数。所以类似于以下内容:

lst = ['blue', 'green', 'green', 'yellow', 'yellow', 'yellow', 'orange', 'orange', 'silver', 'silver', 'silver', 'silver']
lst.sort()

current_color = lst[0] # assuming lst is not empty
count = 0
for c in lst:
    if c == current_color:
        count += 1
    else:
        print('Color:', current_color, 'Total:', count)
        current_color = c
        count = 1
print('Color:', current_color, ', Total:', count) # print the last color

【讨论】:

  • Counter 将列表转换为字典,然后打印元组列表。我正在寻找一种维护列表结构的解决方案,然后使用诸如 .format 之类的方法以及 sort/sorted 来显示上面示例结构中的信息。我肯定会在这里走很长的路,但我正在寻找可变列表的所有灵活性。
  • @slashdotblake 我明白你的意思。我在不使用字典的情况下添加了一个可能的解决方案。第二种解决方案的优点是它不为字典使用任何额外的空间。虽然这是一个很好的练习,但如果空间不是问题,我仍然鼓励您在实际应用程序中使用计数器对象以获得更具可读性的代码。
  • 第二个例子正是我想要解决这个问题的。我浏览了许多 stackoverflow 帖子,但没有一个我能找到这样一个基本的解决方案。
【解决方案2】:

你为什么不看看 collections 模块? 计数器功能将帮助您非常简单地实现目标。

【讨论】:

    【解决方案3】:

    您可以使用itertools.groupby 组合相同颜色的条目。它生成一个对 (key, values) 的迭代器,其中 values 是匹配 key 的元素的生成器。

    我使用退化的sum 来计算值的计数,如this answer,但还有其他选项。

    import itertools
    
    lst = "blue green green yellow yellow yellow orange orange silver silver silver silver".split()
    
    groups = sorted(((key, sum(1 for _ in values))
                     for (key, values) in itertools.groupby(lst)))
    
    for color, count in groups:
        print("Color: {}, Total: {}".format(color, count))
    

    【讨论】:

    • 感谢您的回复。这确实提供了一个解决方案,但我希望在不需要 itertools 的情况下完成它。这一行, sum(1 for _ in values),你为什么使用 _ ?是否忽略列表中每个项目的值。你能再解释一下吗?
    • 您愿意分享一个不使用任何导入模块的解决方案吗?
    【解决方案4】:

    我建议您使用高性能计数器。计数器是将元素存储为字典键的容器,其计数存储为字典值。

    import collections a = ["blue", "green", "green", "yellow", "yellow", "yellow", "orange", "orange", "silver", "silver", "silver", "silver"] counter = collections.Counter(a) colors = counter.keys() for color in colors: print 'Color: %s, Total: %d' % (color, counter[color])

    【讨论】:

      【解决方案5】:

      按照要求不使用导入,这里唯一使用的是str.count列表理解

      lista = [
          'blue', 'green', 'green', 'yellow', 'yellow', 'yellow', 'orange', 
          'orange', 'silver', 'silver', 'silver', 'silver'
      ]
      
      listb = []
      for i in lista:
          if i not in listb:
              listb.append(i)
      
      for i in sorted(listb):
          print('Color: {}, Total: {}'.format(i.ljust(6), lista.count(i)))
      
      Color: blue  , Total: 1
      Color: green , Total: 2
      Color: orange, Total: 2
      Color: silver, Total: 4
      Color: yellow, Total: 3
      

      老实说,你不需要很多工具来完成这项工作,如果有什么我会使用 listb = set(lista) 但你说不 set,我把 .ljust(6) 扔进去是为了好玩,让输出更漂亮

      【讨论】:

      • 这里使用计数函数的例子非常好。欣赏帖子。我相信你打算写第二个列表,listb = []。您的方法和 Slider 的第二种方法是我寻求解决此问题的基本方法。我给了滑块的优势,因为他手动计算了我想做的计数,但我没想到。
      • @slashdotblake 是的,错字!很高兴我们能够提供帮助:)
      猜你喜欢
      • 1970-01-01
      • 2019-09-08
      • 2020-06-09
      • 2016-04-08
      • 1970-01-01
      • 2019-11-13
      • 2021-07-14
      • 1970-01-01
      • 2013-12-03
      相关资源
      最近更新 更多