今日学习进度:集合,函数相关
1.创建集合的三种方法:
使用花括号,元素之间以逗号分隔:{"abc", "bcd"}
使用集合推导式:{s for s in "abc"}
使用类型构造器,也就是set(): set("abc")
2.集合具有随机性
{s for s in "abc"}
{'b', 'a', 'c'}
由于集合是无序的,所以我们不能使用下标索引的方式去访问它
不过我们可以使用 in 和 not in 来判断某个元素是否存在于集合中:
a = {s for s in "abc"}
'a' in a
True
3.如果想要访问集合中的元素,可以使用迭代的方式
for each in a:
print(each)
b
a
c
4.集合的去重功能
集合另外一个特点就是唯一性,利用集合,咱们就可以轻松地实现去重的操作:
>>> set([1, 1, 2, 3, 5])
{1, 2, 3, 5}
检测一个列表中是否存在相同的元素:
>>> s = [1, 1, 2, 3, 5]
>>> len(s) == len(set(s))
False
>>> s = [1, 2, 3, 5]
>>> len(s) == len(set(s))
True
5.集合的运算:
s.copy() | 返回 s 集合的一个浅拷贝 |
s.isdisjoint(other) | 如果 s 集合中没有与 other 容器存在共同的元素,那么返回 True,否则返回 False |
s.issubset(other) | 如果 s 集合是 other 容器的子集(注1),那么返回 True,否则返回 False |
s.issuperset(other) | 如果 s 集合是 other 容器的超集(注2),那么返回 True,否则返回 False |
s.union(*others) | 返回一个新集合,其内容是 s 集合与 others 容器的并集(注3) |
s.intersection(*others) | 返回一个新集合,其内容是 s 集合与 others 容器的交集(注4) |
s.difference(*others) | 返回一个新集合,其内容是存在于 s 集合中,但不存在于 others 容器中的元素(注5) |
s.symmetric_difference(other) | 返回一个新集合,其内容是排除掉 s 集合和 other 容器中共有的元素后,剩余的所有元素 |
Python 也提供了相应的运算符,可以直接进行运算。
检测子集可以使用小于等于号(<=)
>>> s <= set("FishC")
True
那么检测真子集我们可以使用小于号(<)
使用大于号(>)和大于等于号(>=)就是检测真超集和超集
并集使用管道符(|):
>>> s | {1, 2, 3} | set("Python")
{1, 2, 3, 'y', 'h', 'n', 'i', 'P', 's', 'o', 't', 'C', 'F'}
交集使用 and 符号(&):
>>> s & set("Php") & set("Python")
{'h'}
差集使用减号(-):
>>> s - set("Php") - set("Python")
{'s', 'C', 'F', 'i'}
对称差集使用脱字符(^)
注意:使用运算符的话,符号两边都必须是集合类型的数据才可以,不然会报错。
6.不可变集合
Python将集合细分为可变集合与不可变集合,前者是set(),后者是frozenset()。
不可变集合是不能被修改的,一旦被修改会报错。
7.仅适用于set()的方法
update(*others) 方法使用 others 容器中的元素来更新集合:
s = set("abcd")
s
{'b', 'a', 'c', 'd'}
s.update([1,3], "24")
s
{1, 3, '4', 'b', '2', 'd', 'a', 'c'}
intersection_update(*others)、difference_update(*others) 和 symmetric_difference_update(other) 分别是使用前面讲过的交集、差集和对称差集的方式来更新集合
如果希望要单纯地往集合里添加数据,可以使用 add(elem) 方法:
s.add("45")
s
{1, 3, '45', '4', 'b', '2', 'd', 'a', 'c'}
在集合中删除某个元素,可以使用 remove(elem) 或者 discard(elem) 方法:
s.remove("mmm")
Traceback (most recent call last):
File "<pyshell#14>", line 1, in <module>
s.remove("mmm")
KeyError: 'mmm'
s.discard("mmm")
s
{1, 3, '45', '4', 'b', '2', 'd', 'a', 'c'}
删除还有一个 pop() 方法,用于随机从集合中弹出一个元素:
s.pop()
3
s.pop()
'45'
s.pop()
'4'
最后,clear() 方法就是将集合清空
8.可哈希
想要正确地创建字典和集合,是有一个刚性需求的 —— 那就是字典的键,还有集合的元素,它们都必须是可哈希的。
如果一个对象是可哈希的,那么就要求它的哈希值必须在其整个程序的生命周期中都保持不变。
通过hash()函数我们可以获取一个对象的哈希值
Python 中大多数不可变对象是可哈希的,而那些可变的容器则不哈希:
>>> hash("FishC")
2090433017907150752
>>> hash([1, 2, 3])
Traceback (most recent call last):
File "<pyshell#36>", line 1, in <module>
hash([1, 2, 3])
TypeError: unhashable type: 'list'
如果我们把列表换成元组,元组是不可变的对象,那就应该是可哈希的:
>>> hash((1, 2, 3))
529344067295497451
9.嵌套的集合
尽管集合是不可哈希的,所以不能直接嵌套,但是我们可以通过frozenset()来使其变为不可变集合就可以了。
>>> x = frozenset(x)
>>> y = {x, 4, 5}
>>> y
{frozenset({1, 2, 3}), 4, 5}
10.创建和调用函数
我们使用 def 语句来定义函数,紧跟着的是函数的名字,后面带一对小括号,冒号下面就是函数体,函数体是一个代码块,也就是每次调用函数时将被执行的内容:
>>> def myfunc():
... pass
...
>>>
注:pass 是一个空语句,表示不做任何事情,经常是被用来做一个占位符使用的。
调用这个函数,只需要在名字后面加上一对小括号
11.函数的参数
从调用角度来看,参数可以细分为:形式参数(parameter)和实际参数(argument)。
其中,形式参数是函数定义的时候写的参数名字(比如下面例子中的 name 和 times);实际参数是在调用函数的时候传递进去的值(比如下面例子中的 "Python" 和 5)。
>>> def myfunc(name, times):
... for i in range(times):
... print(f"I love {name}.")
...
>>> myfunc("Python", 5)
I love Python.
I love Python.
I love Python.
I love Python.
I love Python.
12.函数的返回值
只需要使用 return 语句,就可以让咱们自己定制的函数实现返回:
>>> def div(x, y):
... z = x / y
... return z
...
>>> div(4, 2)
2.0
如果一个函数没有通过 return 语句返回,它也会自己在执行完函数体中的语句之后,悄悄地返回一个 None 值:
>>> def myfunc():
... pass
...
>>> print(myfunc())
None
13.位置参数
在通常的情况下,实参是按照形参定义的顺序进行传递的:
def myfunc(a, b, c):
return "".join((b, a, c))
myfunc("我", "喜欢", "你")
'喜欢我你'
myfunc("喜欢", "我", "你")
'我喜欢你'
由于在定义函数的时候,就已经把参数的名字和位置确定了下来,我们将 Python 中这类位置固定的参数称之为位置参数。
14.关键字参数
使用关键字参数,我们只需要知道形参的名字就可以:
myfunc(b="我", a="喜欢", c="你")
'我喜欢你'
如果同时使用位置参数和关键字参数,位置参数必须是在关键字参数之前,否则会报错。
15.默认参数
Python 还允许函数的参数在定义的时候指定默认值,这样以来,在函数调用的时候,如果没有传入实参,那么将采用默认的参数值代替
>>> def myfunc(s, vt, o="我"):
... return "".join((o, vt, s))
...
>>> myfunc("游戏", "玩")
'我玩游戏'
默认参数的意义就是当用户没有输入该参数的时候,有一个默认值可以使用,不至于造成错误。
如果用户指定了该参数值,那么默认的值就会被覆盖:
>>> myfunc("游戏", "玩", "你")
'你玩游戏'
这里也有一点是需要注意的,就是如果要使用默认参数,那么应该把它们摆在最后
16.只能使用位置参数:
使用 help() 函数查看函数文档的时候呢,经常会在函数原型的参数中发现一个斜杠(/)
>>> help(abs)
Help on built-in function abs in module builtins:
abs(x, /)
Return the absolute value of the argument.
>>> help(sum)
Help on built-in function sum in module builtins:
sum(iterable, /, start=0)
Return the sum of a 'start' value (default: 0) plus an iterable of numbers
When the iterable is empty, return the start value.
This function is intended specifically for use with numeric values and may
reject non-numeric types.
这表示斜杠左侧的参数必须传递位置参数,不能是关键字参数,举个例子:
>>> abs(-1.5)
1.5
>>> abs(x = -1.5)
Traceback (most recent call last):
File "<pyshell#67>", line 1, in <module>
abs(x = -1.5)
TypeError: abs() takes no keyword arguments
17.只能使用关键字参数:
利用星号(*):
>>> def abc(a, *, b, c):
... print(a, b, c)
这样,参数 a 既可以是位置参数也可以是关键字参数,但参数 b 和参数 c 就必须是关键字参数,才不会报错:
>>> abc(1, 2, 3)
Traceback (most recent call last):
File "<pyshell#98>", line 1, in <module>
abc(1, 2, 3)
TypeError: abc() takes 1 positional argument but 3 were given
>>> abc(1, b=2, c=3)
1 2 3
>>> abc(a=3, b=2, c=1)
3 2 1