集合:
set() ,{'a',}
print(a - b) # a 和 b 的差集
print(a | b) # a 和 b 的并集
print(a & b) # a 和 b 的交集
print(a ^ b) # a 和 b 中不同时存在的元素
字典:
>>> dict_1 = dict([('a',1),('b',2),('c',3)]) #元素为元组的列表
>>> dict_1
{'a': 1, 'b': 2, 'c': 3}
>>> dict_2 = dict({('a',1),('b',2),('c',3)})#元素为元组的集合
>>> dict_2
{'b': 2, 'c': 3, 'a': 1}
>>> dict_3 = dict([['a',1],['b',2],['c',3]])#元素为列表的列表
>>> dict_3
{'a': 1, 'b': 2, 'c': 3}
>>> dict_4 = dict((('a',1),('b',2),('c',3)))#元素为元组的元组
>>> dict_4
{'a': 1, 'b': 2, 'c': 3}
# 字典推导式
p = {i:str(i) for i in range(1,5)}
print("p:",p)
'''
p: {1: '1', 2: '2', 3: '3', 4: '4'}
'''
x = ['A','B','C','D']
y = ['a','b','c','d']
n = {i:j for i,j in zip(x,y)}
print("n:",n)
'''
n: {'A': 'a', 'B': 'b', 'C': 'c', 'D': 'd'}
'''
s = {x:x.strip() for x in ('he','she','I')}
print("s:",s)
'''
s: {'he': 'he', 'she': 'she', 'I': 'I'}
'''
:= 海象运算符,可在表达式内部为变量赋值。Python3.8 版本新增运算符。
在这个示例中,赋值表达式可以避免调用 len() 两次:
if (n := len(a)) > 10:
print(f"List is too long ({n} elements, expected <= 10)")
is 和 ==
is 判断两个变量是否是引用同一个内存地址。
== 判断两个变量是否相等。
如果不用 a = b 赋值,int 型时,在数值为 -5~256(64位系统)时,两个变量引用的是同一个内存地址,其他的数值就不是同一个内存地址了。
也就是,a b 在 -5~256(64位系统)时:
a = 100
b = 100
a is b # 返回 True
其他类型如列表、元祖、字典让 a、b 分别赋值一样的时:
a is b # 返回False
###== 和 is 的区别###
is 判断两个对象是否为同一对象, 是通过 id 来判断的; 当两个基本类型数据(或元组)内容相同时, id 会相同, 但并不代表 a 会随 b 的改变而改变。
== 判断两个对象的内容是否相同, 是通过调用 __eq__() 来判断的。
1、当列表,元组,字典中的值都引用 a,b 时,总是返回 True,不受 a,b 值大小的影响
a=1000
b=1000
list1=[a,3,5]
list2=[b,4,5]
print(list1[0] is list2[0])
tuple1=(a,3,5)
tuple2=(b,4,5)
print(tuple1[0] is tuple2[0])
dict1={6:a,2:3,3:5}
dict2={1:b,2:4,3:7}
print(dict1[6] is dict2[1])
输出结果为:
True
True
True
2、当不引用a,b,直接用具体值来测试时,列表,字典,不受值大小影响,返回True,元组则受 256 值范围的影响,超出范围则地址改变,返回 False。
list1=[1000,3,5]
list2=[1000,4,5]
print(list1[0] is list2[0])
tuple1=(1000,3,5)
tuple2=(1000,4,5)
print(tuple1[0] is tuple2[0])
dict1={6:1000,2:3,3:5}
dict2={1:1000,2:4,3:7}
print(dict1[6] is dict2[1])
输出结果为:
True
False
True
3、当直接用列表、元组、字典本身来测试时,刚好相反,元组返回 True,列表,字典返回 False。
list1=[1000,3,5]
list2=[1000,3,5]
print(list1 is list2)
tuple1=(1000,3,5)
tuple2=(1000,3,5)
print(tuple1 is tuple2)
dict1={1:1000,2:3,3:5}
dict2={1:1000,2:3,3:5}
print(dict1 is dict2)
输出结果为:
False
True
False
##关于 is 和 == 的标识问题##
(1)只要是变量的值相同,标识都相同,没有-5~256的限制,看下面的例子:
a = 100000
b = 100000
if a is b:
print('a 和 b 标识相同,标识为:',id(a))
else:
print('a 和 b 标识不相同,a 标识为:',id(a),'b 标识为:',id(b))
输出结果为:
a 和 b 标识相同,标识为: 2158477874512
(2)同样的如果是负数,仍然没有上述限制:
a = -100000
b = -100000
if a is b:
print('a 和 b 标识相同,标识为:',id(a))
else:
print('a 和 b 标识不相同,a 标识为:',id(a),'b 标识为:',id(b))
输出结果为:
a 和 b 标识相同,标识为: 2137845175632
(3)列表也是一样的,只要是列表项数值一样,那么标识也是一样的。例子如下:
list1 = [10000,20000,30000]
list2 = [10000,12000,15000]
if list1[0] is list2[0]:
print('list1[0] 和 list2[0] 标识相同,标识为:',id(list1[0]))
else:
print('list1[0] 和 list2[0] 标识不相同,list1[0]标识为:',id(list1[0]),'list2[0]标识为:',id(list2[0]))
输出结果为:
list1[0] 和 list2[0] 标识相同,标识为: 1375086286224
(4)元组的标识是跟着变量名的,变量名不一样,标识也不一样,上例子:
tuple1 = (10000,20000,30000)
tuple2 = (10000,12000,15000)
if tuple1[0] is tuple2[0]:
print('tuple1[0] 和 tuple2[0] 标识相同,标识为:',id(tuple1[0]))
else:
print('tuple1[0] 和 tuple2[0] 标识不相同,tuple1[0] 标识为:',id(tuple1[0]),'tuple2[0]标识为:',id(tuple2[0]))
输出结果为:
tuple1[0] 和 tuple2[0] 标识不相同,tuple1[0] 标识为: 1375086286384 tuple2[0]标识为: 1375086286480
(5)字典和列表是一样的,只要是列表项数值一样,那么标识也是一样的。例子如下:
dict1 = {1:10000,2:20000,3:30000}
dict2 = {1:10000,2:12000,3:15000}
if dict1[1] is tuple2[1]:
print('dict1[1] 和 tuple2[1] 标识相同,标识为:',id(dict1[1]))
else:
print('dict1[1] 和 tuple2[1] 标识不相同,dict1[1] 标识为:',id(dict1[1]),'tuple2[1] 标识为:',id(dict2[1]))
输出结果为:
dict1[1] 和 tuple2[1] 标识不相同,dict1[1] 标识为: 1375086286224 tuple2[1] 标识为: 1375086286224
纠正上面 beihangld 评论关于“整数中 1 的数量”问题:由源码分析可知,Python3 整数对象存储为无符号数加上符号位标志,所以不存在“负数”补码形式,因此,计算 “1” 的数量需要按去符号后的无符号数:
cnt=bin(n).count('1')
另外,Python3 无长整,整数长度原则上不限,所以不能以假定的 32 位处理。
##可更改(mutable)与不可更改(immutable)对象##
简单的说就是,不可更改类型传到函数里重新赋值后,两次输出值不一样,而可更改类型传到函数里对对象的"属性" 重新赋值后输出值一样
在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。
不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。
可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。
python 函数的参数传递:
不可变类型:类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。
可变类型:类似 c++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响
声明函数时,参数中星号 * 可以单独出现,例如:
def f(a,b,*,c):
return a+b+c
如果单独出现星号 * 后的参数必须用关键字传入。
>>> def f(a,b,*,c):
... return a+b+c
...
>>> f(1,2,3) # 报错
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() takes 2 positional arguments but 3 were given
>>> f(1,2,c=3) # 正常
6
>>>
匿名函数
python 使用 lambda 来创建匿名函数。
所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。
lambda 只是一个表达式,函数体比 def 简单很多。
lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
语法
lambda 函数的语法只包含一个语句,如下:
lambda [arg1 [,arg2,.....argn]]:expression
#!/usr/bin/python3
# 可写函数说明
sum = lambda arg1, arg2: arg1 + arg2
# 调用sum函数
print ("相加后的值为 : ", sum( 10, 20 ))
print ("相加后的值为 : ", sum( 20, 20 ))
### 强制位置参数 ###
Python3.8 新增了一个函数形参语法 / 用来指明函数形参必须使用指定位置参数,不能使用关键字参数的形式。
在以下的例子中,形参 a 和 b 必须使用指定位置参数,c 或 d 可以是位置形参或关键字形参,而 e 或 f 要求为关键字形参:
def f(a, b, /, c, d, *, e, f):
print(a, b, c, d, e, f)
以下使用方法是正确的:
f(10, 20, 30, d=40, e=50, f=60)
以下使用方法会发生错误:
f(10, b=20, c=30, d=40, e=50, f=60) # b 不能使用关键字参数的形式
f(10, 20, 30, 40, 50, f=60) # e 必须使用关键字参数的形式