import collections
import sys
def count_and_sort_strings(file_path):
# 使用生成器逐行读取文件,避免一次性加载整个文件到内存
def read_lines():
with open(file_path, 'r', encoding='utf-8') as file:
for line in file:
yield line.strip()
counter = collections.Counter(read_lines())
sorted_counter = sorted(counter.items(), key=lambda item: item[1], reverse=True)
for string, count in sorted_counter:
print(f"{string}: {count}")
if __name__ == "__main__":
if len(sys.argv)!= 2:
print("Usage: python script.py <file_path>")
else:
count_and_sort_strings(sys.argv[1])
算法和数据结构说明
- 生成器(Generator):通过自定义的
read_lines
生成器函数逐行读取文件,而不是一次性将整个1GB文件读入内存,这样可以大大减少内存占用。每次迭代时,只在内存中保留当前行的字符串。
collections.Counter
:使用Counter
来统计每个字符串出现的次数。Counter
是一个字典的子类,非常适合这种计数场景,它会自动维护每个元素的计数。
- 排序:使用Python内置的
sorted
函数,对Counter
对象转换后的列表进行排序。排序依据是每个字符串的出现次数,并且设置reverse=True
以实现从高到低排序。
避免内存溢出问题的方式
- 逐行读取:通过生成器逐行读取文件,而不是一次性将整个文件读入内存。这样在任何时刻,内存中只有当前正在处理的一行数据,即使文件非常大也不会造成内存溢出。
Counter
的高效性:collections.Counter
内部实现针对计数场景进行了优化,它不会占用过多的额外内存。每个字符串及其计数在Counter
对象中以键值对的形式存储,相比于手动实现计数逻辑,Counter
更节省内存和代码量。