hukey

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

 

分类:

技术点:

相关文章:

  • 2021-11-22
  • 2021-05-31
  • 2022-02-15
  • 2018-08-23
  • 2021-04-02
  • 2021-11-22
  • 2021-06-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2021-11-22
  • 2021-12-08
  • 2021-09-20
  • 2021-11-22
  • 2022-12-23
相关资源
相似解决方案