【问题标题】:Counter module and dictionaries计数器模块和字典
【发布时间】:2019-12-19 14:06:40
【问题描述】:

在之前的练习中,我编写了一个代码,用于打印 csv 文件中每座山脉的高度。你可以在这里找到它:

import csv

def mountain_height(filename):
    """ Read in a csv file of mountain names and heights.  
    Parse the lines and print the names and heights. 
    Return the data as a dictionary. 
    The key is the mountain and the height is the value.
    """

    mountains = dict()
    msg = "The height of {} is {} meters."
    err_msg = "Error: File doesn't exist or is unreadable."

    # TYPE YOUR CODE HERE.
    try:
        with open('mountains.csv', 'r') as handle:
            reader = csv.reader(handle, delimiter=',')

            for row in reader:
                name = row[0]
                height = row[1]
                mountains[name] = int(height)

            for name, height in mountains.items():
                print("The height of {names} is {heights} meters.".format(names=name, heights=height))

    except:
        print("Error: Something wrong with your file location?")
        return None

我不确定它是否理想,但它似乎有效。

这是 csv 文件的预览: mountains.csv

现在,我必须使用集合的模块计数器重写此代码,以计算每个山脉被提及的次数。每行包含一座山、它的高度和它所在的范围。

我还需要添加一个字典,记录特定范围内所有山脉的高度。我必须为高度值使用一个列表。键将是范围名称。每次在该范围内有一座新山时,都必须将高度添加到该键的列表中。例如,读取所有数据后,mountains['Himalayas'] == [8848, 8586, 8516, 8485, 8201, 8167, 8163, 8126, 8091, 8027]。 (“喜马拉雅”是范围。)

输出应该是打印前 2 个范围并将范围名称添加到计数器。 然后,打印每个范围内山脉的平均高度。在所有打印后返回包含范围及其山高列表的字典对象。

我对 Counter 模块有非常小的概念,我对这项任务感到不知所措。 您对从哪里开始有什么建议吗?

这是我目前所得到的:

from collections import Counter
from collections import defaultdict
from statistics import mean
def mountain_ranges(filename):
    ranges = Counter()
    heights = defaultdict(list)

提前谢谢你....

【问题讨论】:

  • 您能否显示示例 CSV 和预期数据
  • 你为什么“必须”使用Counter
  • 我认为这更像是一个问题解决策略的问题?想一想您将如何“手动”完成,确定工作流程中的可分组步骤(子任务),并查找某些预定义的库是否可以帮助您完成某些步骤(例如此处的 Counter)。分而治之……
  • @Alderven 我在帖子中添加了 CSV 文件预览的链接,希望对您有所帮助!
  • @PyPingu 我必须使用它,因为它是我正在关注的互联网课程中数据提取练习的要求。但是,我以前从未使用过它,而且我还处于课程的开始阶段,有点迷茫......

标签: python dictionary counter


【解决方案1】:

以下将打印出您要求的内容,并返回计数器和高度字典。

import csv
from collections import defaultdict, Counter
from statistics import mean


def mountain_height(filename):
    """ Read in a csv file of mountain names and heights.  
    Parse the lines and print the names and heights. 
    Return the data as a dictionary. 
    The key is the mountain and the height is the value.
    """
    range_heights = defaultdict(list)
    range_count = Counter()
    # TYPE YOUR CODE HERE.
    try:
        with open(filename, 'r') as handle:
            reader = csv.reader(handle, delimiter=',')
            for row in reader:
                if row:
                    name = row[0]
                    height = row[1]
                    mrange = row[2]
                    range_heights[mrange].append(int(height))
                    range_count[mrange] += 1
    except:
        print("Error: Something wrong with your file location?")
        return None

    print("The 2 most frequent ranges are:")
    for mrange in range_count.most_common(2):
        print(f"{mrange[0]} has {mrange[1]} mountains")
    print("The average heights of each range are:")
    for mrange, heights in range_heights.items():
        print(f"{mrange} -- {mean(heights)}m")

    return range_count, range_heights


counts, heights = mountain_height('mountains.csv')


The 2 most frequent ranges are:
Himalayas has 10 mountains
Karakoram has 4 mountains
The average heights of each range are:
Himalayas -- 8321m
Karakoram -- 8194.25m

所以你知道,我个人不认为在这里使用Counter 是必要的或“正确”的做事方式,但既然这是你需要的,那就是我给你的。事实上,这甚至不是您可以在这里使用 Counter 的唯一方法 - 您可以在遍历行时创建每个范围的列表,然后只需应用 Counter(list_of_ranges) 但对于较大的文件,这意味着创建内存中的一个大列表再次看起来毫无意义。

为了清楚起见,我个人在没有Counter 的情况下获得计数的解决方案是只使用range_heights 字典和字典理解,如下所示:

range_counts = {r: len(heights) for r, heights in range_heights.items()}

【讨论】:

  • 恕我直言,在这里发布 c&p 解决方案并不是很有帮助,而且您对内存消耗/优化的想法也没有达到目标 - 看来 OP 应该学习如何利用现成的点点滴滴。
  • 我本来可以链接到 Counter 上的文档,但我觉得自己很慈善,所以我基本上只是将文档中的示例插入到 OPs 代码中。
  • PyPingu 的回答很有帮助,因为我现在明白使用“计数器”在这里不是最有效的。我现在需要在列表中打印一个范围内每座山脉的高度,我现在可以尝试自己做这个,因为我有基地!谢谢 PyPingu ;)
猜你喜欢
  • 2012-03-26
  • 2022-01-19
  • 2016-04-11
  • 1970-01-01
  • 2019-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多