美文网首页Python
13.Collections模块

13.Collections模块

作者: 小哲1998 | 来源:发表于2020-03-15 10:13 被阅读0次

    一、实验目的

    • Counter 类
    • defaultdict 类
    • namedtuple 类

    二、知识要点

    首先我们通过:

    import collections
    

    导入Collections模块,这个模块实现了一些很好的数据结构,能够解决各种实际问题。

    1.Counter类

    在这里我们需要先来了解一下哈希值的概念,通常来说,所有Python内置的不可变对象都是可哈希的,同时,可变容器都是不可哈希的,有关可变对象与不可变对象在8.函数的对象中(可更改、不可更改对象)。官方文档对于哈希(hashable)的解释是这样的:

    如果一个对象在其生命周期内有一个固定不变的哈希值 (这需要__hash__()方法) 且可以与其他对象进行比较操作 (这需要__eq__()方法) ,那么这个对象就是可哈希对象 (hashable) 。可哈希对象必须有相同的哈希值才算作相等。
    由于字典 (dict) 的键 (key) 和集合 (set) 内部使用到了哈希值,所以只有可哈希 (hashable) 对象才能被用作字典的键和集合的元素。
    所有python内置的不可变对象都是可哈希的,同时,可变容器 (比如:列表 (list) 或者字典 (dict) ) 都是不可哈希的。用户自定义的类的实例默认情况下都是可哈希的;它们跟其它对象都不相等 (除了它们自己) ,它们的哈希值来自id()方法。

    较为详细的解释参考文章:简书:聊一聊Python中的hashable和immutable


    Counter 是一个有助于 hashable 对象计数的 dict 子类。它是一个无序的集合,其中 hashable 对象的元素存储为字典的键,它们的计数存储为字典的值,计数可以为任意整数,包括零和负数。

    2.defaultdict类

    defaultdict 是内建 dict类的子类,它覆写了一个方法并添加了一个可写的实例变量。其余功能与字典相同。defaultdict() 第一个参数提供了 default_factory 属性的初始值,默认值为Nonedefault_factory 属性值将作为字典的默认数据类型。所有剩余的参数与字典的构造方法相同,包括关键字参数。同样的功能使用 defaultdict 比使用 dict.setdefault 方法快。

    3.namedtuple类

    命名元组有助于对元组每个位置赋予意义,并且让我们的代码有更好的可读性和自文档性。你可以在任何使用元组地方使用命名元组。

    三、实验内容

    1.统计文件中某些单词的出现次数

    在这里我们使用.collections.Counter中的re类,使用most_common()函数进行统计文章中出现次数最多的10个单词


    • 代码:
    from collections import Counter
    import re
    path = 'LICENSE.txt'
    words = re.findall('\w+', open(path).read().lower())
    print(Counter(words).most_common(10))
    
    • 结果:
    [('the', 277), ('of', 160), ('or', 146), ('and', 129), ('in', 112), ('to', 97), ('software', 95), ('this', 95), ('any', 76), ('1', 71)]
    
    • 函数解释:

    re.findall:

    对 string 返回一个不重复的 pattern 的匹配列表, string 从左到右进行扫描,匹配按找到的顺序返回。如果样式里存在一到多个组,就返回一个组合列表;就是一个元组的列表(如果样式里有超过一个组合的话)。空匹配也会包含在结果里。


    使用Counter对象中的element()方法,其返回的序列中,依照计数重复元素相同次数,元素顺序是无序的。


    • 代码:
    from collections import Counter
    
    c = Counter(a=4, b=2, c=0, d=-2)
    print(list(c.elements()))
    
    • 结果:
    ['a', 'a', 'a', 'a', 'b', 'b']
    
    2.使用defaultdict创建列表
    • 代码:
    from collections import defaultdict
    
    s = [('zz', 99), ('wyf', 98), ('wcc', 745), ('yxy', 666)]
    d = defaultdict(list)
    for k, v in s:
        d[k].append(v)
    print(d.items())
    
    • 结果:
    dict_items([('zz', [99]), ('wyf', [98]), ('wcc', [745]), ('yxy', [666])])
    

    即使 defaultdict对象不存在某个键,它会自动创建一个空列表。


    3.使用namedtuple定义命名元组
    • 代码:
    from collections import namedtuple
    
    Point = namedtuple('Point', ['x', 'y'])  # 定义命名元组
    p = Point(10, y=20)  # 创建一个对象
    print(p.x, p.y)
    print(p[0], p[1])  # 像普通元组那样访问元素
    x, y = p  # 元组拆封
    print(x, y)
    
    • 结果:
    10 20
    10 20
    10 20
    

    四、实验结果

    1.学生教师操作

    写一个脚本使之具备如下的功能:
    基类为PersonPerson的两个派生类分别为StudentTeacher,在每个函数中除了需要有构造函数外,其他函数及说明如下:

    • Person.get_details:返回包含人名的字符串
    • Person.get_grade:返回0
    • Student.__init__:返回 Student 对象,采用name, branch, year,grade4 个参数
    • Student.get_details:返回包含学生具体信息的字符串
    • Stduent.get_grade:以Pass: X, Fail: X来统计自己的成绩情况(A,B,C 为 Pass, 如果得了 D 就认为是 Fail)
    • Teacher.__init__:返回 Teacher 对象,采用字符串列表作为参数,包括name,papers,grade3个参数
    • Teacher.get_details:返回包含教师具体信息的字符串
    • Teacher.get_grade:自动统计出老师班上学生的得分情况并按照频率的高低以 A: X, B: X, C: X, D: X 的形式打印出来

    具体要求如下:

    1. 根据命令行中的第一个参数 teacher 或者 student 来判断最终输出的格式。
    2. 命令行中第二个输入的参数是需要统计的字符串

    • 代码:
    import sys
    from collections import Counter
    
    
    class Person(object):
        def __init__(self, name):
            self.name = name
    
        def get_details(self):
            return self.name
    
        def get_grade(self):
            return 0
    
    
    class Student(Person):
        def __init__(self, name, branch, year, grade):
            Person.__init__(self, name)
            self.branch = branch
            self.year = year
            self.grade = grade
    
        def get_details(self):
            return "{} studies {} and is in {} year.".format(self.name, self.branch, self.year)
    
        def get_grade(self):
            common = Counter(self.grade).most_common(4)
            pass_s = 0
            fail_s = 0
            for item in common:
                if item[0] != 'D':
                    pass_s += item[1]
                else:
                    fail_s += item[1]
            print("pass: {}, Fail: {}".format(pass_s, fail_s))
    
    
    class Teacher(Person):
        def __init__(self, name, papers, grade):
            Person.__init__(self, name)
            self.papers = papers
            self.grade = grade
    
        def get_details(self):
            return "{} teaches {}".format(self.name, ','.join(self.papers))
    
        def get_grade(self):
            s = []
            common = Counter(self.grade).most_common(4)
            for i, j in common:
                s.append("{}:{}".format(i, j))
            print(', '.join(s))
    
    
    person = Person('Sachin')
    if sys.argv[1] == 'student':
        student1 = Student("Kushal", "CSE", 2005, sys.argv[2])
        student1.get_grade()
    else:
        teacher1 = Teacher("Prachad", ['C', 'C++'], sys.argv[2])
        teacher1.get_grade()
    
    
    • 结果:
    (venv) F:\NewPython\13>python teacher_grade.py teacher ABCCBABAAD
    A:4, B:3, C:2, D:1
    
    (venv) F:\NewPython\13>python teacher_grade.py student ABBDDCBADA
    pass: 7, Fail: 3
    

    相关文章

      网友评论

        本文标题:13.Collections模块

        本文链接:https://www.haomeiwen.com/subject/duyfehtx.html