zoukankan      html  css  js  c++  java
  • [ Python ] set集合及函数的使用

    1. set类型

    set 和 dict 类似,也是一组 key 的集合,但是不存储 value. 由于 key  不重复,所以,在 set 中, 没有重复的 key 集合是可变类型

    (1)集合的创建

    # 第一种方式创建 set 类型
    >>> print(type(set1), set1)
    <class 'set'> {1, 3, 6, 'z', 'a', 'b'}
    
    # 第二种方式创建 set 类型
    >>> set2 = set(['z', 'a', 'b', 3, 6, 1])
    >>> print(type(set2), set2)
    <class 'set'> {1, 3, 6, 'z', 'a', 'b'}
    
    # 第三种方式创建 set 类型
    >>> set3 = set('hello')
    >>> print(type(set3), set3)
    <class 'set'> {'o', 'e', 'l', 'h'}
    

    2. set 工厂函数

    (1)add(self, *args, **kwargs)

      新增一个元素到集合

    set1 = {'a', 'z', 'b', 4, 6, 1}
    set1.add(8)
    set1.add('hello')
    print(set1)
    
    # 执行结果:
    # {'b', 1, 'a', 4, 6, 8, 'hello', 'z'}
    

    (2) clear()
      清空所有集合元素

    set1 = {'a', 'z', 'b', 4, 6, 1}
    set1.clear()
    print(set1)
    
    # 执行结果:
    # set()
    

    (3)copy()
        拷贝整个集合并赋值给变量

    set1 = {'a', 'z', 'b', 4, 6, 1}
    set2 =set1.copy()
    print(set2)
    
    # 执行结果:
    # {1, 'a', 4, 6, 'b', 'z'}
    

    (4)pop()
        随机删除集合中一个元素,可以通过变量来获取删除的元素

    set1 = {'a', 'z', 'b', 4, 6, 1}
    ys = set1.pop()
    print('set1集合:', set1)
    print('删除的元素:', ys)
    
    # 执行结果:
    # set1集合: {4, 6, 'z', 'a', 'b'}
    # 删除的元素: 1
    

    (5)remove(self, *args, **kwargs)
        删除集合中指定的元素,如果该集合内没有该元素就报错

    set1 = {'a', 'z', 'b', 4, 6, 1}
    set1.remove('a')
    print(set1)
    set1.remove('x')
    print(set1)
    
    # 执行结果:
    # {1, 4, 6, 'b', 'z'}
    # Traceback (most recent call last):
    #   File "D:/learn_python/learn_python/day13/s1.py", line 43, in <module>
    #     set1.remove('x')
    # KeyError: 'x'
    

    (6)discard(self, *args, **kwargs)
        删除集合中指定的元素,如果该集合内没有该元素也不会报错

    set1 = {'a', 'z', 'b', 4, 6, 1}
    set1.discard('a')
    print(set1)
    set1.discard('y')
    print(set1)
    
    # 执行结果:
    # {1, 4, 6, 'b', 'z'}
    # {1, 4, 6, 'b', 'z'}
    

    pop() 、remove() 、 discard() 三个集合删除函数比较:
        pop() 随机删除集合中一个元素remove() 删除集合中指定的元素,如果集合中没有指定的元素,程序报错!
        discard() 删除集合中指定的元素,如果集合中没有指定的元素,程序正常运行。

    (7) intersection  & :交集; union | :并集合; difference - : 差集

    set1 = {'a', 'b', 'x', 'y'}
    set2 = {'i', 'j', 'b', 'a'}
    
    # 交集
    print(set1 & set2)
    print(set1.intersection(set2))
    
    # 执行结果:
    # {'a', 'b'}
    # {'a', 'b'}
    
    
    # 并集
    print(set1 | set2)
    print(set1.union(set2))
    
    # 执行结果:
    # {'y', 'j', 'a', 'b', 'x', 'i'}
    # {'y', 'j', 'a', 'b', 'x', 'i'}
    
    # 差集
    print(set1 - set2)
    print(set1.difference(set2))
    print(set2 - set1)
    print(set2.difference(set1))
    
    # 执行结果:
    # {'y', 'x'}
    # {'y', 'x'}
    # {'j', 'i'}
    # {'j', 'i'}
    

    (8)difference_update ()
        求差集,并赋值给源集合

    set1 = {'a', 'b', 'x', 'y'}
    set2 = {'i', 'j', 'b', 'a'}
    set1.difference_update(set2)
    print(set1)
    
    # 执行结果:
    # {'y', 'x'}
    

    (9)intersection_update()
        求交集,并赋值给源集合

    set1 = {'a', 'b', 'x', 'y'}
    set2 = {'i', 'j', 'b', 'a'}
    
    set1.intersection_update(set2)
    print(set1)
    
    # 执行结果:
    # {'b', 'a'}
    

    (10)symmetric_difference()  和 ^ 符号效果一样
        求交叉补集

    set1 = {'a', 'b', 'x', 'y'}
    set2 = {'i', 'j', 'b', 'a'}
    
    print('symmetric_difference:', set1.symmetric_difference(set2))
    print('^:', set1 ^ set2)
    
    # 执行结果:
    # symmetric_difference: {'x', 'i', 'y', 'j'}
    # ^: {'x', 'i', 'y', 'j'}
    

    (11)symmetric_difference_update()
      求交叉补集并赋值给源集合

    set1 = {'a', 'b', 'x', 'y'}
    set2 = {'i', 'j', 'b', 'a'}
    
    set1.symmetric_difference_update(set2)
    print(set1)
    
    # 执行结果:
    # {'y', 'i', 'j', 'x'}
    

    (12)update()
        更新集合,参数为可迭代对象

    set1 = {'a', 'b', 'x', 'y'}
    
    set1.update(('hello', 'world'))
    print(set1)
    
    # 执行结果:
    # {'hello', 'world', 'b', 'a', 'y', 'x'}
    

    add() 和 update() 比较:
        add(): 只能添加一个元素到集合
        update(): 可以添加多个元素到集合,参数为 iterable

    使用 frozenset 定义不可变集合

    s = frozenset('hello')
    print(s)
    
    # 执行结果:
    # frozenset({'h', 'e', 'o', 'l'})
    

     使用 frozenset 定义的集合,没有 add 或者 pop 等方法

    3. 函数

    (1)函数表现形式
    python中函数的定义方法:

    def test(x):
            "The function definitions"
            x += 1
            return x
    

    def: 定义函数关键字
    test: 函数名(): 内可定义参数"": 文档描述(非必要,强烈建议添加函数信息描述)
    x+=1 : 泛指代码块或程序处理逻辑
    return: 定义返回值

    调用运行:可以带参数也可以不带函数名()

    使用函数的好处:
        代码重用
        保持一致性,易维护
        可扩展

    函数返回值:
        返回值 = 0 : 返回 None
        返回值 = 1 : 返回 object
        返回值数 > 1: 返回 tuple

    (2)函数的参数

    建议参考:廖老师python3函数的参数

    4. 全局变量和局部变量

    如果函数的内容无 global 关键字,优先读取局部变量,能读取全局变量,无法对全局变量重新赋值 NAME='FFF',但是对于可变类型,可以对内部元素进行操作;
    如果函数中有 global 关键字,变量本质上就是全局变量,可读取可赋值 NAME='fff'

    name = 'hkey'
    
    def test1():
            name = 'xiaofei'
            print(name)
    
    def test2():
            global name
            name = 'xxxx'
    
    test1()
    test2()
    print('name:', name)
    
    # 执行结果:
    # xiaofei
    # name: xxxx
    

     

    如果函数内无 global 关键字:

        (1)有声明局部变量

    NAME = ['xiaofei', 'hkey']
    
    def test():
            NAME = 'sky'
            print('name:', NAME)
    
    test()
    
    # 执行结果:
    # name: sky
    

        (2)无声明局部变量
        对于可变类型,可以对内部元素进行操作;

    NAME = ['xiaofei', 'hkey']
    
    def test():
            NAME.append('sky')
            print('name:', NAME)
    
    test()
    
    # 执行结果:
    # name: ['xiaofei', 'hkey', 'sky']
    

    如果函数内有 global 关键字

        (1)有声明局部变量

    NAME = ['xiaofei', 'hkey']
    
    def test():
            # 获取全局变量 NAME
            global NAME
            # 打印全局变量 NAME
            print('global NAME:', NAME)
            # 将全局变量 NAME 修改为 'test_func'
            NAME = 'test_func'
            # 打印修改后的全局变量
            print('name:', NAME)
    
    test()
    
    # 执行结果:
    # global NAME: ['xiaofei', 'hkey']
    

        (2)无声明局部变量

    NAME = ['xiaofei', 'hkey']
    
    def test():
            # 获取全局变量 NAME
            global NAME
            # 打印全局变量 NAME
            print(NAME)
            # 修改全局变量为 ['sky']
            NAME = ['sky']
            # 追加全局变量
            NAME.append('blue')
            # 打印修改后的全局变量
            print(NAME)
    
    test()
    
    # 执行结果:
    ##['sky','blue']
    

    在代码中我们规定,全局变量名全部使用大写,而局部变量用小写,这边就避免变量名的混淆;

        (3)nonlocal 关键字用来在函数或者其他作用域中使用外层变量

    def outer():
            num = 10
            def inner():
                    nonlocal num    # nonlocal 关键字声明
                    num = 100       # 修改作用域 num 使用方法和 global 一致
                    print(num)      
            inner()
            print(num)          # 该 num 已经在 inner() 中修改过的
    
    outer()
    
    # 执行结果:
    # 100
    # 100
    

     5. 递归函数

       (1)函数即变量

    def test():
            pass
    
    t = test    # 把函数当作值 赋值给变量 t
    print(t)
    
    # 执行结果:
    # <function test at 0x00000245A2FBA048>
    

       

      (2)递归函数

          在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
          递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都写成循环的方式,但循环的逻辑不如递归清晰。

    def fact(n):
            if n == 1:
                    return 1
            return n * fact(n - 1)
    
    print(fact(5))
    
    # 执行过程如下:
    # 
    # ===> fact(5)
    # ===> 5 * fact(4)
    # ===> 5 * (4 * fact(3))
    # ===> 5 * (4 * (3 * fact(2)))
    # ===> 5 * (4 * (3 * (2 * fact(1))))
    # ===> 5 * (4 * (3 * (2 * 1)))
    # ===> 5 * (4 * (3 * 2))
    # ===> 5 * (4 * 6)
    # ===> 5 * 24
    # ===> 120
    

        递归函数就像问路一样,有去有回。A问B,B在问C,C知道答案返回给B,B在返回给A
        必须有一个明确的结束条件
        每次进入更深一层的递归时,问题规模相比上次递归应有所减少
        递归效率不高

      (3)尾递归优化

          尾递归是指,在函数返回的时候,调用自身本身,并且,return 语句不能包含表达式。

    def fact(n):
            return fact_iter(n, 1)
    
    def fact_iter(num, product):
            if num == 1:
                    return product
            # return 语句不能包含表达式。递归本身无论调用多少次,都只占用一个栈帧
            return fact_iter(num - 1, num * product)
    
    # 运行过程:
    # fact(5)
    # ===> fact_iter(5, 1)
    # ===> fact_iter(4, 5)
    # ===> fact_iter(3, 20)
    # ===> fact_iter(2, 60)
    # ===> fact_iter(1, 120)
    # ===>120
    
  • 相关阅读:
    [CSP校内集训]2019.10.16数学专题
    Knights of the Round Table(缩点+判奇环) poj 2942 && 洛谷SP2878
    机房测试7:exam(二进制+模拟)
    机房测试9:gift(单调队列优化dp)
    机房测试9:hotel(神奇dp)
    机房测试8:question(求最大1矩阵:悬线法 or 二分)
    机房测试7:paint(分治+st表)
    机房测试6:矿石(优先队列)
    机房测试6:括号序列(hash+栈 )
    bzoj1123 && 洛谷 P3469 tarjan割点的运用
  • 原文地址:https://www.cnblogs.com/hukey/p/9242339.html
Copyright © 2011-2022 走看看