目录java
封装与解构属于Python语言的一种特性,它使用起来很像其余语言中的"逗号表达式"
,但内部原理是不一样的,在某些场景下:好比变量交换复制时使用,显得很是优雅。python
封装故名思议就是装箱,把多个值使用逗号分隔,组合在一块儿,本质上来看,其返回的是一个元组,只是省略了小括号。(必定要区别与C语言的逗号表达式)数组
In [91]: t1 = (1,2) # 定义一个元组 In [92]: t2 = 1,2 # 省略括号,其内部仍是会封装成元组 In [93]: t1 Out[93]: (1, 2) In [94]: t2 Out[94]: (1, 2) In [95]: type(t1) Out[95]: tuple In [96]: type(t2) Out[96]: tuple
解构,解构,就是把箱子解开,在Python中表示从线性结构中把元素解开,而且顺序的赋值给其余变量,须要注意的是,解构时接受元素的变量,须要放在等式的左边,而且数量要和右边解开的元素的个数一致。数据结构
In [97]: t1 Out[97]: (1, 2) In [98]: a,b = t1 # 表示把1赋给a,把2赋给b In [99]: a Out[99]: 1 In [100]: b Out[100]: 2 In [101]: a,b,c = t1 # 当接受元素的变量多余解构的元素时,会提示ValueError,反之相同 --------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-101-2e8ad53e5fc7> in <module> ----> 1 a,b,c = t1 ValueError: not enough values to unpack (expected 3, got 2) In [102]:
了解了封装与解构,那么回想一下当咱们须要进行变量交换的时候,是否能够经过封装与解构进行优化呢?当咱们在其余语言中进行a,b变量的值的交换,咱们须要一个中间变量temp,即:a = temp,a = b,b = temp
,在Python中咱们能够省略。测试
>>> a = 1 >>> b = 200 >>> a,b = b,a # 这样就完成了变量的交换了,是否是很方便 >>> a 200 >>> b 1 >>>
为何可使用这种骚操做,是由于Python在进行变量赋值时,会先计算等式右边的表达式,封装起来,而后再进行解构,赋给对应位置上的变量。而且还提供了其余更便捷的方法好比*号。优化
*号
: 使用方式为: *变量名
,贪婪的吸取解构的元素造成一个列表,不管可否吸取,都会返回一个列表。_号
:表示丢弃一个变量(其实是使用_
接受变量,可是使用这么一个符号,就表示咱们不想用它)In [1]: t = list(range(5)) In [2]: t Out[2]: [0, 1, 2, 3, 4] In [3]: head,*mid,tail = t In [4]: head Out[4]: 0 In [5]: mid Out[5]: [1, 2, 3] In [6]: tail Out[6]: 4
须要注意的是:code
# 1 从[1,(2,3,4),5]中取出4来 >>> _,(*_,a),_ = [1,(2,3,4),5] >>> a >>> 4 # 环境变量JAVA_HOME=/usr/bin/java,返回环境变量名和路径 >>> env,path = 'JAVA_HOME=/usr/bin/java'.split('=') >>> env,path >>> ('JAVA_HOME','/usr/bin/java') 或者 In [9]: env, _, path = 'JAVA_HOME=/usr/bin/java'.partition('=') In [10]: env,path Out[10]: ('JAVA_HOME', '/usr/bin/java')
解构是Python提供的很好的功能,能够方便的提取复杂的数据结构的值,配置_使用时,会更加便捷。对象
集合set在Python中是一个很是重要的非线性结构
,它使用{}
表示,用三个词总结集合的特色就是:可变的
、无序的
、不重复
。它的官方解释以下:索引
可hash对象
组成的集。交集(intersection)
、并集(union)
、差集(difference)
、对称差集(symmetric difference)
等。x in set
,len(set)
,for x in set
等操做。set不会记录元素的位置以及元素加入集合的顺序,因此set不支持索引
,切片
或者其余的类序列的操做。ip
什么是可hash对象,能够简单的理解为能够被hash()计算的对象,在Python中,可hash对象是不可变类型的,好比tuple, str, int, 等等。
Python提供了两种定义一个集合的方式,set()
和 set(iterable)
,他们的用法以下:
set() -> new empty set object --> 返回一个空的set对象 set(iterable) -> new set object --> 返回一个set对象,元素有iterable填充
例如:
In [44]: s1 = set() In [45]: s2 = set(range(5)) # {0, 1, 2, 3, 4} In [46]: s3 = set(list(range(10))) # 外面使用list进行转换,画蛇添足,{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} In [47]: s4 = {} # 这种方式其实是建立了一个字典 In [48]: s4 Out[48]: {} In [50]: type(s4) Out[50]: dict In [51]: s5 = {(1,3),3,'a'} In [52]: s6={[1,2],(1,2,),1,2} # list属于不可hash对象,因此没法添加到set中去 --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-52-237c72203405> in <module> ----> 1 s6={[1,2],(1,2,),1,2} TypeError: unhashable type: 'list' In [53]:
set是可变的类型,那就意味着,咱们能够对set进行增长、删除、修改等操做。
set提供了两种定义一个集合的方式,add
和 update
,他们的用法以下:
s.add() --> None --> 在集合s中添加一个元素,若是元素存在,则什么都不作(去重特性)。(就地修改) s.update(*other) --> None --> 把*others个可迭代可hash对象,和s进行并集,而后赋给s。(就地修改)
例
In [62]: s Out[62]: {1, 2, 3} In [63]: s.add('abc') # 把'abc'看成一个元素添加进去 In [64]: s Out[64]: {1, 2, 3, 'abc'} In [65]: s.add((1,2,3)) # 把(1,2,3) 看成一个元素添加进去 In [66]: s Out[66]: {(1, 2, 3), 1, 2, 3, 'abc'} In [67]: s.update(range(5),'abcdef',[5,6,7,8]) # 多个可迭代可hash对象取并集 In [68]: s Out[68]: {(1, 2, 3), 0, 1, 2, 3, 4, 5, 6, 7, 8, 'a', 'abc', 'b', 'c', 'd', 'e', 'f'}
set提供了多种定义一个集合的方式,好比 remove
,pop
,他们的用法以下:
s.remove() --> None --> 在集合s中删除一个元素,这个元素必须存在集合s中,不然会报KeyError异常 s.pop() --> item --> 在集合s中随便弹出一个元素,并返回元素的自己,若是集合自己为空,那么会提示KeyError异常 s.discard(elem) --> None --> 在集合s中删除一个元素,若是元素不存在集合中,那么什么也不作 s.clear() --> None --> 清空集合
例
In [71]: s Out[71]: {(1, 2, 3), 0, 1, 2, 3, 4, 5, 6, 7, 8, 'a', 'abc', 'b', 'c', 'd', 'e', 'f'} In [72]: s.remove(0) In [73]: s Out[73]: {(1, 2, 3), 1, 2, 3, 4, 5, 6, 7, 8, 'a', 'abc', 'b', 'c', 'd', 'e', 'f'} In [74]: s.remove(1000) # 不存在集合内的元素,删除会报异常 --------------------------------------------------------------------------- KeyError Traceback (most recent call last) <ipython-input-74-9d9da17ab719> in <module> ----> 1 s.remove(1000) KeyError: 1000 In [76]: s Out[76]: {(1, 2, 3), 1, 2, 3, 4, 5, 6, 7, 8, 'a', 'abc', 'b', 'c', 'd', 'e', 'f'} In [77]: s.pop() Out[77]: 1 In [78]: s Out[78]: {(1, 2, 3), 2, 3, 4, 5, 6, 7, 8, 'a', 'abc', 'b', 'c', 'd', 'e', 'f'} In [82]: s1 Out[82]: set() In [84]: s1.pop() # 空集合会报异常 --------------------------------------------------------------------------- KeyError Traceback (most recent call last) <ipython-input-84-095118de218b> in <module> ----> 1 s1.pop() KeyError: 'pop from an empty set' In [85]: s Out[85]: {(1, 2, 3), 4, 5, 6, 7, 8, 'a', 'abc', 'b', 'c', 'd', 'e', 'f'} In [86]: s.discard(1000) # 直接删除,不会返回 In [89]: s.discard(4) In [90]: s Out[90]: {(1, 2, 3), 5, 6, 7, 8, 'a', 'abc', 'b', 'c', 'd', 'e', 'f'} In [92]: s.clear() In [93]: s Out[93]: set()
上来咱们须要先想一个问题,为何要修改set呢?修改的本质是什么?
可是set是容器,能够被迭代
因此set不能像list那样,经过索引修改元素,由于它无序的特性,修改其实等同于删除、再添加而已。
咱们说既然set是容器,那么咱们就能够对容器内的元素进行判断,那么就须要使用成员判断符 in
和 not in
了。
In [95]: s = set(range(20)) In [96]: 1 in s Out[96]: True In [97]: 10000 not in s Out[97]: True
咱们知道在list,str这种
线性结构
中进行成员判断
时,它的时间复杂度是O(n)
的,由于须要遍历,可是在set中就很简单了,它只须要把要判断的元素进行hash,找到set中对应的门牌号,把里面的数据拽出来,看看是否是相同。 这种操做一般都是O(1)
的,因此在set中,成员判断效率很高
,固然在dict类型
中,也是如此。
线性结构的查询时间复杂度是O(n)
,即随着数据规模的这不过大而增长耗时,set、dict等结构,内部使用的是hash值做为key,时间复杂度能够作到O(1)
查询时间和数据规模无关,在python中可hash对象有(都属于不可变类型)
简单来讲,所谓的一个集合,就是将数个对象归类而分红为一个或数个形态万千的大小总体。 通常来说,集合是具备某种特性的事物的总体,或是一些确认对象的聚集。构成集合的事物或对象称做元素或是成员。集合的元素能够是任何事物,能够是人,能够是物,也能够是字母或数字等。 (此解释来自于维基百科)
差集:集合中除去和其余集合共有的部分
这些是小学数学基础概念哦,兄弟们。
经过集合运算,咱们能够方便的对求出集合的差集、并集等,Python的集合除了提供了大量的集合运算方法还提供了很多的特殊符号用来表示集合运算。
将集合A和集合B全部元素合并在一块儿,组成的集合称为集合A和集合B的并集
s.union(*other) --> new set object --> 把多个集合和集合s进行合并,返回一个新的集合对象 --> 使用 | 表示 s.update(*other) --> None --> 把*others个可迭代可hash对象,和s进行并集,而后赋给s。(就地修改) --> 使用 != 表示
集合A和集合B,由全部属于A且属于B的元素组成的集合。
s.intersection(*other) --> new set object --> 返回多个集合的交集 --> 使用 & 表示 s.intersection_update(*other) --> None --> 获取多个集合的交集,就地进行修改 --> 使用 &= 表示
集合A和B,由全部属于A且不属于B的元素组成的集合。
s.difference(*others) --> new set object --> 返回集合s和其余多个集合的差集 --> 使用 - 表示 s.difference_update(*other) --> None --> 返回集合s和其余多个集合的差集,就地进行修改 --> 使用 -= 表示
不属于集合A和集合B交集的其余元素组成的集合,数学表达式为:(A-B) U (B-A)。
s.symmetric_difference(*other) --> new set object --> 返回和另外一些集合的对称差集 --> 使用 ^ 表示 s.symmetric_difference_update --> None --> 返回和另外一些集合的对称差集,就地修改 --> 使用 ^= 表示
s.issubset(other) --> bool --> 判断当前集合是不是另外一个集合的子集 --> 使用 <= 表示 set1 < set2 : 判断set1是不是set2的真子集 s.isssuperset(other) --> bool --> 判断当前集合是不是other的超集 --> 使用 >= 表示 set1 > set2 : 判断set1是不是other的真超集 s.isdisjoint(other) --> bool --> 判断当前集合和另外一个集合有没有交集