随笔 - 52  文章 - 0  评论 - 2  阅读 - 16522

Python知识点复习_2

内容:

5.python中setfrozenset方法和区别
6.python函数基础以及函数参数简解
7.python的文件操作方法
8.python常用内置函数

python基础知识

5.python中set和frozenset方法和区别

set(可变集合)与frozenset(不可变集合)的区别:

set无序排序且不重复,是可变的,有add(),remove()等方法。既然是可变的,所以它不存在哈希值。
基本功能包括关系测试和消除重复元素. 集合对象还支持union(联合), intersection(交集), difference(差集)和sysmmetric difference(对称差集)等数学运算.
sets 支持 x in set, len(set),和 for x in set。作为一个无序的集合,sets不记录元素位置或者插入点。
因此,sets不支持 indexing, 或其它类序列的操作。
frozenset是冻结的集合,它是不可变的,存在哈希值,好处是它可以作为字典的key,也可以作为其它集合的元素。缺点是一旦创建便不能更改,没有addremove方法。





一、集合的创建

set()和 frozenset()工厂函数分别用来生成可变和不可变的集合。如果不提供任何参数,默认会生成空集合。
如果提供一个参数,则该参数必须是可迭代的,即,一个序列,或迭代器,或支持迭代的一个对象,例如:一个列表或一个字典。


s=set('cheeseshop')  使用工厂方法创建
s
{'h', 'c', 'o', 's', 'e', 'p'}
type(s)
<type 'set'>

s={'chessseshop','bookshop'}直接创建,类似于list的[]和dict的{},不同于dict的是其中的值,set会将其中的元素转换为元组
s
{'bookshop', 'chessseshop'}
type(s)
<type 'set'>

不可变集合创建:
t=frozenset('bookshop')
t
frozenset({'h', 'o', 's', 'b', 'p', 'k'})





二、更新可变集合

用各种集合内建的方法和操作符添加和删除集合的成员:


s.add('z')  #添加
s
set(['c', 'e', 'h', 'o', 'p', 's', 'z'])
s.update('pypi') #添加
s
set(['c', 'e', 'i', 'h', 'o', 'p', 's', 'y', 'z'])
s.remove('z') #删除
s
set(['c', 'e', 'i', 'h', 'o', 'p', 's', 'y'])
s -= set('pypi')#删除
s
set(['c', 'e', 'h', 'o', 's'])
del s  #删除集合



只有可变集合能被修改。试图修改不可变集合会引发异常。

t.add('z')
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'frozenset' object has no attribute 'add'





三、成员关系 (in, not in)

'k' in s
False
'k' in t
True
'c' not in t
True





四、集合等价/不等价

s == t
False
s != t
True
u = frozenset(s)
s == u
True
set('posh') == set('shop')
True





五、子集/超集

set('shop') < set('cheeseshop')
True
set('bookshop') >= set('shop')
True





六、遍历访问集合中的值(可变集合和非可变都支持)

s=set('cheeseshop')
s
{'h', 'c', 'o', 's', 'e', 'p'}
for i in s:
    print(i)    
h
c
o
s
e
p


t=frozenset('bookshop')
t
frozenset({'h', 'o', 's', 'b', 'p', 'k'})
for i in t:
    print(i)    
h
o
s
b
p
k





七、集合类型操作符(所有的集合类型)

1.联合( | )

    1 两个集合的联合是一个新集合,该集合中的每个元素都至少是其中一个集合的成员,即,
    属于两个集合其中之一的成员。联合符号有一个等价的方法,union().

    2 >>> s | t

    3 set(['c', 'b', 'e', 'h', 'k', 'o', 'p', 's'])



2.交集( & )

    1 你可以把交集操作比做集合的 AND(或合取)操作。两个集合的交集是一个新集合,
    该集合中的每个元素同时是两个集合中的成员,即,属于两个集合的成员。交集符号有一个等价的方法,intersection()

    2 >>> s & t

    3 set(['h', 's', 'o', 'p']



3.差补/相对补集( – )

    1 两个集合(s 和 t)的差补或相对补集是指一个集合 C,该集合中的元素,只属于集合 s,
    而不属于集合 t。差符号有一个等价的方法,difference().

    2 >>> s - t

    3 set(['c', 'e'])



4.对称差分( ^ )

    1 和其他的布尔集合操作相似, 对称差分是集合的 XOR(又称"异或 ").

    2 两个集合(s 和 t)的对称差分是指另外一个集合 C,该集合中的元素,只能是属于集合 s 或者集合 t 的成员,
    不能同时属于两个集合。对称差分有一个等价的方法,symmetric_difference().

    3 >>> s ^ t

    4 set(['k', 'b', 'e', 'c'])



5.混合集合类型操作

    1 上面的示例中,左边的 s 是可变集合,而右边的 t 是一个不可变集合. 
    注意上面使用集合操作运算符所产生的仍然是可变集合,但是如果左右操作数的顺序反过来,结果就不一样了

    2 >>> t | s

    3 frozenset(['c', 'b', 'e', 'h', 'k', 'o', 'p', 's'])

    4 >>> t ^ s

    5 frozenset(['c', 'b', 'e', 'k'])

    6 >>> t - s frozenset(['k', 'b'])



如果左右两个操作数的类型相同, 既都是可变集合或不可变集合, 则所产生的结果类型是相同的,
但如果左右两个操作数的类型不相同(左操作数是 set,右操作数是 frozenset,或相反情况),
则所产生的结果类型与左操作数的类型相同。





八、可变集合类型的方法

1 s.update(t) 用 t 中的元素修改 s, 即,s 现在包含 s 或 t 的成员
2 s.intersection_update(t) s 中的成员是共同属于 s 和 t 的元素。
3 s.difference_update(t) s 中的成员是属于 s 但不包含在 t 中的元素
4 s.symmetric_difference_update(t) s 中的成员更新为那些包含在 s 或 t 中,但不 是 s
5 和 t 共有的元素
6 s.add(obj) 在集合 s 中添加对象 obj
7 s.remove(obj) 从集合 s 中删除对象 obj;如果 obj 不是集合 s 中的元素(obj not in s),将引发 KeyError 错误
8 s.discard(obj) 如果 obj 是集合 s 中的元素,从集合 s 中删除对象 obj;
9 s.pop() 删除集合 s 中的任意一个对象,并返回它
10 s.clear() 删除集合 s 中的所有元素





九、集合类型操作符、函数和方法

函数/方法名 等价运算符 说明
所有集合类型:

1 len(s) 集合基数: 集合 s 中元素的个数
2 set([obj]) 可变集合工厂函数; obj 必须是支持迭代的,由 obj 中
3 的元素创建集合,否则创建一个空集合
4 frozenset([obj]) 不可变集合工厂函数; 执行方式和 set()方法相同,
5 但它返回的是不可变集合
6 obj in s 成员测试:obj 是 s 中的一个元素吗?
7 obj not in s 非成员测试:obj 不是 s 中的一个元素吗?
8 s == t 等价测试: 测试 s 和 t 是否具有相同的元素?
9 s != t 不等价测试: 与==相反
10 s < t (严格意义上)子集测试; s != t 而且 s 中 所 有
11 的元素都是 t 的成员
12 s.issubset(t) s <= t 子集测试(允许不严格意义上的子集): s 中所有的元素
13 都是 t 的成员
14 s > t (严格意义上)超集测试: s != t 而且 t 中所有的元素
15 都是 s 的成员
16 s.issuperset(t) s >= t 超集测试(允许不严格意义上的超集): t 中所有的元素
17 都是 s 的成员
18 s.union(t) s | t 合并操作: s 或 t 中的元素
19 s.intersec- tion(t) s & t 交集操作: s 和 t 中的元素
20 s.difference(t) s - t 差分操作: s 中的元素,而不是 t 中的元素
21 s.symmetric_difference(t)s ^ t 对称差分操作:s 或 t 中的元素,但不是 s 和 t 共有
22 的元素
23 s.copy() 复制操作:返回 s 的(浅复制)副本



仅用于可变集合:

1 s.update(t) s |= t (Union) 修改操作: 将 t 中的成员添加 s
2 s.intersection_update(t) s &= t 交集修改操作: s 中仅包括 s 和 t 中共有的成员
3 s.difference_update(t) s -= t 差修改操作: s 中包括仅属于 s 但不属于 t 的成员
4 s.symmetric_
5 difference_
6 update(t) s ^= t 对称差分修改操作: s 中包括仅属于 s 或仅属于 t 的成员
7 s.add(obj) 加操作: 将 obj 添加到 s
8 s.remove(obj) 删除操作: 将 obj 从 s 中删除;如果 s 中不存在obj,将引发 KeyError
9 s.discard(obj) 丢弃操作: remove() 的 友 好 版 本 - 如果 s 中存在 obj,从 s 中删除它
10 s.pop() Pop 操作: 移除并返回 s 中的任意一个元素
11 s.clear() 清除操作: 移除 s 中的所有元素

6.python函数基础以及函数参数简解

python中函数分为函数、内置函数

Python所有的内置函数

自定义函数要使用def语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回。调用函数,使用函数名+()

def 关键字+函数名():
    函数体
    return  可以终止函数,默认返回None
下面 hello()函数,没有返回值。如果保存了返回值,该值为 None>>> def hello():
... print 'hello world'
>>>
>>> res = hello()
hello world
>>> res
>>> print res
None
>>> type(res)
<type 'None'>




python里的函数可以返回一个值或者对象。只是在返回一个容器对象的时候有点不同,看起来像是能返回多个对象。

def foo():
return ['xyz', 1000000, -98.6]
def bar():
return 'abc', [42, 'python'], "Guido"
foo()函数返回一个列表, bar()函数返回一个元组。 由于元组语法上不需要一定带上圆括号, 所以让人真的以为可以返回多个对象。

定义函数文档

文档的以贯例是多行字符串,第一行以大写字母开头以句点(.)结束(注:中文在V3.3中也可以),第二行是空行,从第三行开始是详细描述。
强烈建议,为你重要的函数写文档字符串要遵循此贯例

def foo():
    '''
    foo() -- properly created doc string
    '''
    函数体

函数的形参和实参

形参,只是一个形式,表示占据一个参数位置。
实参,是一个具体的参数,有它的实际意义。

Python中函数的实参有4种形式,分别是:

位置或关键字参数、仅位置的参数、任意数量的位置参数、任意数量的关键字参数

第一种:位置或关键字参数
这种参数是Python中默认的参数类型,定义这种参数后,可以通过位置参数,或者关键字参数的形式传递参数,这个是Python的默认参数类型

>>> def func(arg1, arg2="World!"):
    print (arg1, arg2)
## func可以通过位置参数形式调用
>>>func("Hello", "MitchellChu")
Hello MitchellChu
## 也可以通过关键字参数的形式来调用func
>>>func(arg1="Hello", arg2="World!")
Hello World!
## 当然,混合的方式也是完全没有问题的
>>>func("Hello", arg2="World!")
Hello World!
## 不过如果你不能将关键字参数优先于位置参数传递给函数(方法)
## 这个调用方法是不能接受的,因为优先级不一样.后面会说
>>> func(arg1="Hello", "World!")
SyntaxError: positional argument follows keyword argument

第二种方式:仅适用位置参数的形式
这种形式在需要将参数传递给函数(方法)时,仅能通过位置参数的传递方式。这种形式对于Python的开发者来说,暂时并没有办法使用。这种形式现在仅存在Python的很多内建的函数上:

>>> abs(-3)
abs(a=3)
## Traceback (most recent call last):
##   File "<stdin>", line 1, in <module>
## TypeError: abs() takes no keyword arguments
>>> pow(x=2,y=3)
## Traceback (most recent call last):
##   File "<stdin>", line 1, in <module>
## TypeError: pow() takes no keyword arguments
>>> pow(2,3)
## 8

第三种:任意数量的位置参数(带单个星号参数)
任意数量的位置参数在定义的时候是需要一个星号前缀来表示,在传递参数的时候,可以在原有参数的后面添加任意多个参数,这些参数将会被放在元组内提供给函数(方法):

定义的时候,我们需要添加单个星号作为前缀

def func(arg1, arg2, *args):
    print (arg1, arg2, args)
##调用的时候,前面两个必须在前面,前两个参数是位置或关键字参数的形式,所以你可以使用这种参数的任一合法的传递方法
>>> func("hello", "Tuple, values is:", 2, 3, 3, 4)
hello Tuple, values is: (2, 3, 3, 4)
##多余的参数将自动被放入元组中提供给函数使用.如果你需要传递元组给函数,你需要在传递的过程中添加*号
## 请看下面例子中的输出差异:
>>> func("hello", "Tuple, values is:", (2, 3, 3, 4))
hello Tuple, values is: ((2, 3, 3, 4),)
>>> func("hello", "Tuple, values is:", *(2, 3, 3, 4))
hello Tuple, values is: (2, 3, 3, 4)

第四种:任意数量的关键字参数(带两个星号参数)
任意数量的关键字参数在定义的时候,参数名称前面需要有两个星号(**)作为前缀,这样定义出来的参数,在传递参数的时候,可以在原有的参数后面添加任意多个关键字参数,关键字参数是使用[参数名称=参数值]的形式进行传递:

>>> func("hello", "Dict, values is:", x=2, y=3, z=3)
hello Dict, values is: {'z': 3, 'x': 2, 'y': 3}

>>> func("hello", "Dict., values is:", **{'x':2, 'y':3, 'z':3,})
hello Dict., values is: {'z': 3, 'x': 2, 'y': 3}

>>> func("hello", "Dict., values is:", s=3, **{'x':2, 'y':3, 'z':3,})
hello Dict., values is: {'z': 3, 's': 3, 'x': 2, 'y': 3}

错误方法:
#提供多了参数
>>> func("hello", "Dict., values is:", {'x':2, 'y':3, 'z':3})
Traceback (most recent call last):
    File "<pyshell#57>", line 1, in <module>
    func("hello", "Dict., values is:", {'x':2, 'y':3, 'z':3})
TypeError: func() takes 2 positional arguments but 3 were given

## 提供了重复的参数
>>> func("hello", "Dict., values is:", y=3, **{'x':2, 'y':3, 'z':3,})
Traceback (most recent call last):
    File "<pyshell#59>", line 1, in <module>
    func("hello", "Dict., values is:", y=3, **{'x':2, 'y':3, 'z':3,})
TypeError: func() got multiple values for keyword argument 'y'

总结:四种参数形式中仅有第二种Python没有提供定义的方法,其他三种在定义的时候也需要注意,定义的时候应该根据Python的解析规律进行定义,其中:
位置或关键字参数应该在最前面,其中,没有默认值的应该在有默认值的参数前面
任意数量位置参数应该放在所有位置或关键字参数的后面
任意数量关键字参数应该放在任意数量位置参数的后面
注意:任意数量位置参数和任意数量关键字参数只能在定义中定义一次。

各种参数的混合使用例子

def func(arg1, arg2='default', *args, **kwargs):
    print ("arg1=%s, arg2=%s, args=%s, kwargs=%s" % (arg1, arg2, args, kwargs))
func(1)
func(1,2)
func(1,2,3,4)
func(1,2,3,4,x=1,y=2)
func(1,2,x=1)
func(arg1=1)
func(1,x=1)

思考:函数接受变量作为参数时,接受的是变量的值还是变量的引用?

函数局部变量和全局变量:
在局部中调用全局变量(读取全局变量默认不用写。修改时需要),当全局变量为列表和字典,局部引用区域引用时不使用global时也是可以修改,不能重新赋值。全局变量与局部变量名称冲突时,在函数体内部优先使用局部变量

>>> li=[11,22,33]
>>> def  name(li):
    li=li.append(44)    #全局变量在函数体内由于是引用,所以可以别修改,但是不能被赋值
>>> name(li)
>>> print(li)
[11, 22, 33, 44]

>>> li=[11,22,33]
>>> def  name(li):
    li='hello'     #函数体内对全局变量赋值,结果没有改变
>>> name(li)
>>> print(li)
[11, 22, 33, 44]


>>> li=[11,22,33]
>>> def  name(arg):
    global li            #使用global,可以对全局变量进行修改,不建议使用
    li='hello world'
>>> name(li)
>>> print(li)
hello world

lambda表达式

lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
lambda表达式是起到一个函数速写的作用。允许在代码内嵌入一个函数的定义。

>>> f2      =   lambda      a1:    a1+100 
# f2函数名称     关键字  函数参数  函数体
>>> f2(18)
118

posted on   亚城木CC  阅读(66)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示