Python之路【1】:简介与入门
一,什么是python
Python(英国发音:/ pa θ n/ 美国发音:/ pa θɑ n/),是一种面向对象、直译式的计算机程序语言;创始人Guido van Rossum
二,Python能做什么
Python是一门综合性的语言,几乎能在计算机上通过python做任何事情,一下是python应该最广泛的几个方面:
1,网络应用:web网站,服务器后台服务等
2,科学计算:科学运算:随着NumPy、SciPy、matplotlib、ETS等众多程序库的开发,Python越来 越适合于做科学计算。
3,GUI程序:python 供了多个图形开发界面的库,包括PyQt,WxPython,自带的有Tkinter, 这些库允许 Python 程序员很方便的创建完整的、功能健全的 GUI 用户界面。
4,系统管理工具:Python可以是做运维人员最喜欢用的语言了,可以用它来轻松的开发 自动化管理工具、监控程序等,事实上现在很多开源软件也都是用 Python 开发的,如 用于 IT 配置管理的 SaltStack\Ansible, 做虚拟化的 OpenStack,做备份用的 Bacula 等。
5,其他程序:python写爬虫,做小游戏等。
三,Python的优缺点
优点:
1,Python 的定位是“优雅”、“明确”、“简单”。
2,开发效率非常高,Python有强大的第三方库。
3,高级语言--无需考虑内存一类的底层细节。
4,可移植性--由于开源本质,python已被移植到许多平台。
5,可扩展性。
6,可嵌入性。
缺点:
1,速度慢,Python的运行速度比c语言确实慢很多,跟Java比也要慢些,但这里所指的运行速度慢在大多数情况下用户是无法直接感知到的,必须借助测试工具才能体现出来,比如你用 C 运一个程序花了 0.1s,用 Python 是 0.01s,这样 C 语言直接比 Python 快了 10s,算是非 常夸张了,但是你是无法直接通过肉眼感知的,因为一个正常人所能感知的时间最小单 位是 0.15-0.4s 左右。
2,代码不能加密,因为python是解释性语言,它的源码都是以明文形式存放的。
3,线程不能利用多CPU问题,这是Python被人诟病最多的一个缺点,GIL即全局解释器 锁(Global Interpreter Lock),是计算机程序设计语言解释器用于同步线程的工具,使 得任何时刻仅有一个线程在执行,Python 的线程是操作系统的原生线程。
四,Python安装
安装过程略,仅提供官方网址:http://www.python.org
五,Python解释器
当我们编写 Python 代码时,我们得到的是一个包含 Python 代码的以 .py 为扩展名的文本
文件。要运行代码,就需要 Python 解释器去执行 .py 文件。
由于整个 Python 语言从规范到解释器都是开源的,所以理论上,只要水平够高,任何人都 可以编写 Python 解释器来执行 Python 代码(当然难度很大)。事实上,确实存在多种 Python 解释器。
CPython:这个解释器是用C语言开发的,所以叫CPython
IPython:IPython 是基于 CPython 之上的一个交互式解释器,也就是说,IPython 只是在交互方式上 有所增强,但是执行 Python 代码的功能和 CPython 是完全一样的。CPython 用 >>> 作为 示符,而 IPython 用 In [序号]: 作为 示符。
PyPy:PyPy 是另一个 Python 解释器,它的目标是执行速度。PyPy 采用 JIT 技术,对 Python 代 码进行动态编译(注意不是解释),所以可以显著 高 Python 代码的执行速度。
Jython:Jython 是运行在 Java 平台上的 Python 解释器,可以直接把 Python 代码编译成 Java 字节 码执行。
IronPython:ronPython 和 Jython 类似,只不过 IronPython 是运行在微软.Net 平台上的 Python 解释器, 可以直接把 Python 代码编译成.Net 的字节码。
总结:
Python 的解释器很多,但使用最广泛的还是 CPython。如果要和 Java 或.Net 平台交互, 最好的办法不是用 Jython 或 IronPython,而是通过网络调用来交互,确保各程序之间的独 立性。
好了,正式开始代码之路
第一个Python程序
查看一下自己的python版本,如果太老的话就赶紧升级吧,建议用Python2.x最高版,官方已经说了Python2.7为终结版会支持到2020年
$ python -V
Python 2.7.10
接下来创建一个文件名为:myfirstpy.py
$ cat myfirstpy.py #命名规范,以.py结尾
#!/usr/bin/env python #在程序的第一行声明要使用的解释器类型,这句话等于是告诉操作系统要用 什么解释器来解释这个程序。
print "Hello,World!" #用 print 语法将后面的字符串打印到屏幕上,和 shell 脚本的 echo、java 和
c 的 printf 是一个意思噢。
print "Goodbye,World!"
执行,有两种方式
1,#这种执行方式就算没有在程序第一行声明解释器类型也会执行成功,因为在运行程序的时候使用的是python myfirstpy.py ,开始就声明了解释器
$ python myfirstpy.py
Hello,World!
Goodbye,World!
2,#这种执行方式首先需要对该文件赋予执行权限然后直接./myfirstpy.py就可以执行,如果没有在第一行声明解释器那么执行就会失败
$ chmod +x myfirstpy.py
$ ./myfirstpy.py
Hello,World!
Goodbye,World!
六,Python变量及字符串
数据类型
计算机顾名思义就是可以做数学计算的机器,因此,计算机程序理所当然地可以处理各种数值。但是,计算机能处理的远不止数值,还可以处理文本、图形、音频、视频、网页等各种各样的数据,不同的数据,需要定义不同的数据类型。在Python中,能够直接处理的数据类型有以下几种:
1、整数
Python可以处理任意大小的整数,当然包括负整数,在Python程序中,整数的表示方法和数学上的写法一模一样,例如:1,100,-8080,0,等等。
计算机由于使用二进制,所以,有时候用十六进制表示整数比较方便,十六进制用0x前缀和0-9,a-f表示,例如:0xff00,0xa5b4c3d2,等等。
2、浮点数
浮点数也就是小数,之所以称为浮点数,是因为按照科学记数法表示时,一个浮点数的小数点位置是可变的,比如,1.23x10^9和12.3x10^8是相等的。浮点数可以用数学写法,如1.23,3.14,-9.01,等等。但是对于很大或很小的浮点数,就必须用科学计数法表示,把10用e替代,1.23x10^9就是1.23e9,或者12.3e8,0.000012可以写成1.2e-5,等等。
整数和浮点数在计算机内部存储的方式是不同的,整数运算永远是精确的(除法难道也是精确的?是的!),而浮点数运算则可能会有四舍五入的误差。
3、字符串
字符串是以''或""括起来的任意文本,比如'abc',"xyz"等等。请注意,''或""本身只是一种表示方式,不是字符串的一部分,因此,字符串'abc'只有a,b,c这3个字符。
4、布尔值
布尔值和布尔代数的表示完全一致,一个布尔值只有True、False两种值,要么是True,要么是False,在Python中,可以直接用True、False表示布尔值(请注意大小写),也可以通过布尔运算计算出来。
布尔值可以用and、or和not运算。
and运算是与运算,只有所有都为 True,and运算结果才是 True。
or运算是或运算,只要其中有一个为 True,or 运算结果就是 True。
not运算是非运算,它是一个单目运算符,把 True 变成 False,False 变成 True。
5、空值
空值是Python里一个特殊的值,用None表示。None不能理解为0,因为0是有意义的,而None是一个特殊的空值。
此外,Python还提供了列表、字典等多种数据类型,还允许创建自定义数据类型,我们后面会继续讲到
例子1(字符串常用功能)
*移除空白
$ python3
Python 3.5.1 (v3.5.1:37a07cee5969, Dec 5 2015, 21:12:44)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> name = input("name:") #未做操作前字符串前面的空格会显示出来
name: Adair Jie
>>> name
' Adair Jie'
>>> name = input("name:").strip() #加了操作后字符串前面的空格没了
name: Adair Jie
>>> name
'Adair Jie'
>>> name = input("name:").strip("A") #还可以指定清除内容
name:Adair Jie
>>> name
'dair Jie'
*分割
*长度
*索引
*切片
七,条件判断与缩进
IF...ELSE和缩进
if 判断条件:
执行语句……
else:
执行语句……
例子1,性别判断:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
sex = input("请输入您的性别(boy or girl)")
if sex == "girl":
print ("OK,you are a girl")
elif sex == "boy":
print ("Oh,you are a boy")
else:
print ("Are you pervert!")
例子2,猜lucky number,定义lunky number为6 (if...elfi...else)
#/usr/bin/env python
# -*- coding:utf-8 -*-
lucky_num = 6
input_num = int(input("请输入你的Lucky number:")) #将用户输入转成字符串
if input_num == lucky_num:
print ("恭喜您猜中了")
elif input_num > lucky_num:
print ("你猜的数字大了些!")
else:
print ("你猜的数字小了些!")
例子3,猜lucky number(while True:+break实现)
#/usr/bin/env python
# -*- coding:utf-8 -*-
lucky_num = 6
while True:
input_num = int(input("请输入你的Lucky number:")) #将用户输入转成字符串
if input_num == lucky_num:
print ("恭喜您猜中了")
break #此处break表示正确就会结束程序,而不会陷入死循环
elif input_num > lucky_num:
print ("你猜的数字大了些!")
else:
print ("你猜的数字小了些!")
例子4,猜lucky number(whiel 优化(精简代码))
# -*- coding:utf-8 -*-
lucky_num = 6
input_num = -1
while input_num != lucky_num:
input_num = int(input("请输入你的Lucky number:")) #将用户输入转成字符串
if input_num > lucky_num:
print ("你猜的数字大了些!")
elif input_num < lucky_num:
print ("你猜的数字小了些!")
print ("恭喜您猜中了")
例子5,循环次数限制
#!/usr/bin/env python
# -*- coding:utf-8 -*-
lucky_num = 6
input_num = -1
#计数器
guess_count = 0
while lucky_num != input_num and guess_count < 3:
print ("guess count:",guess_count)
input_num = int(raw_input("Please input your lucky numbers:"))
if input_num < lucky_num:
print ("The real num is smaller!")
elif input_num > lucky_num:
print ("The real num is bigger!")
else:
print ("Bingo!")
例子6,for循环+次数限制
#!/usr/bin/env python
# -*- coding:utf-8 -*-
lucky_num = 19
input_num = -1
#计数器
guess_count = 0
for i in range(3):
input_num = int(raw_input("Please input your lucky numbers:"))
if input_num < lucky_num:
print ("The real num is smaller!")
elif input_num > lucky_num:
print ("The real num is bigger!")
else:
print ("Bingo!")
break
#当上面的条件不满足,条件不满足就走下面的语句
else:
print ("Too many retrys..")
列表:可以在一个变量里存多个信息,且可以单独取出需要的值
$ python3
Python 3.5.1 (v3.5.1:37a07cee5969, Dec 5 2015, 21:12:44)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> name_list = ["adair","python","hugo"]
>>> name_list
['adair', 'python', 'hugo']
查看列表可用的方法
>>> dir(name_list)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
>>>
例子,列表基本操作
*索引(每一个元素都会对应一个标记,群从0开始)以上面的列表为例
>>> name_list[1]
'python'
>>> name_list[2]
'hugo'
>>> name_list[0]
'adair'
>>>
*切片
*追加(默认放到最后,)
>>> name_list.append("Java")
>>> name_list
['adair', 'python', 'hugo', 'Java']
>>> name_list.append("python")
>>> name_list
['adair', 'python', 'hugo', 'Java', 'python']
>>> name_list.index("python") #通过index方法找到python的索引
1
>>> name_list.count("python") #通过cout方法确定有多少个python
2
>>> name_list.insert(2,"cpython") #通过insert在第二个位置插入cpython
>>> name_list
['adair', 'python', 'cpython', 'hugo', 'Java', 'python']
>>> name_list.pop() #通过pop来删除一个,明确的是每次都删除最后一个
'python'
>>> name_list.pop()
'Java'
>>> name_list.remove("cpython") #指定删除
>>> name_list
['adair', 'python', 'hugo']
>>>
>>> name_list #通过reverse来反转
['adair', 'python', 'hugo']
>>> name_list.reverse()
>>> name_list
['hugo', 'python', 'adair']
>>> name_list #通过sort进行排序,特殊字符排在前面,然后是数字,然后是_,然后再是字母
['adair', 'hugo', 'python', '!', '*', '_', '99', '55']
>>> name_list.sort()
>>> name_list
['!', '*', '55', '99', '_', 'adair', 'hugo', 'python']
>>>
>>> name_list.insert(5,"cpython") #多增加两个cpython
>>> name_list.insert(2,"cpython")
>>> name_list
['!', '*', 'cpython', '55', '99', '_', 'cpython', 'adair', 'hugo', 'python']
>>> for i in range(name_list.count('cpython')): #通过for循环删除多个值
... name_list.remove("cpython")
...
>>> name_list
['!', '*', '55', '99', '_', 'adair', 'hugo', 'python']
>>>
变量与赋值:
Python中的变量不需要声明,变量的赋值操作既是变量声明和定义的过程。
每个变量在内存中创建,都包括变量的标识,名称和数据这些信息。
每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。
等号(=)用来给变量赋值。
等号(=)运算符左边是一个变量名,等号(=)运算符右边是存储在变量中的值。例如:
$ python3
Python 3.4.3 (default, Mar 26 2015, 22:03:40)
[GCC 4.9.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> name = "Adair Jie" #此处加了引号,因为引号里的内容是字符串
>>> age = 21 #数字不用引号,如果用了引号就会变成字符串
>>> print(name,age)
Adair Jie 21
>>> a = 3 #定义变量a等于3,即a指向3,且3为a而存在
>>> b = a #定义变量b等于a,此处等于把a的参数传给了b,即b等于3,b指向3
>>> print (a,b) #此时打印结果为3 3
3 3
>>> a = 5 #再次定义变量a等于5,即a指向5,此时a等于5,原来3为a存在的意义就没有了,根据python的回收机制,会将3从内存中拿走,但b依旧没变,就是说b指向的是a的值还是指向3,此时3变成为b而存在了
>>> print (a,b) #此时打印结果为5 3
5 3
>>>
通过内存地址来看变量的变化关系:
内存地址=>>变量存放在内存中的地址
id内置函数,可以看变量存放在内存中的地址
例子:
$ python3
Python 3.4.3 (default, Mar 26 2015, 22:03:40)
[GCC 4.9.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> a = 3
>>> b = a
>>> id(a),id(b)
(10408128, 10408128)
>>> a = 5
>>> id(a),id(b)
(10408192, 10408128)
>>>
变量定义的规则:
变量名只能是 字母、数字或下划线的任意组合
变量名的第一个字符不能是数字
不能有特殊字符,不能有空格
以下关键字不能声明为变量名
['and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'exec', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'not', 'or', 'pass', 'print', 'raise', 'return', 'try', 'while', 'with', 'yield']
用户交互
Python3.x
$ python3
Python 3.4.3 (default, Mar 26 2015, 22:03:40)
[GCC 4.9.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> name = input("Please input your name:") #用户输入的值会存放在name这个变量中
Please input your name:Adair Jie
>>> print (name)
Adair Jie
>>>
Python2.x
$ python2
Python 2.7.9 (default, Apr 2 2015, 15:33:21)
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> name = raw_input("Please input your name:") #在2.x中使用raw_input
Please input your name:Adair Jie
>>> name
'Adair Jie'
>>> input #2.x中也有input函数
<built-in function input>
>>> name2 = input("PLease input you name:")
PLease input you name:Jack
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in <module>
NameError: name 'Jack' is not defined
#此处报错说没有定义Jack
>>> name2 = input("PLease input you name:")
PLease input you name:"Jack" #在次测试在输入值的时候加入引号,发现可以正常执行
>>> name2 #变量值可以正常输出
'Jack'
区别比较
python2 python3
input() ===> eval(input)
raw_input ===> input()
例子:
$ python2
Python 2.7.9 (default, Apr 2 2015, 15:33:21)
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> n = "rain" #定义变量a=“rain"
>>> name2 = input("Please input your name:")
Please input your name:n
>>> print name2 #最终也可以正常执行
rain
>>>
$ python3
Python 3.4.3 (default, Mar 26 2015, 22:03:40)
[GCC 4.9.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> n = "rain"
>>> eval('n') #此处的eval其实就等于这个eval函数去遍历了一遍内存,看看内存里面是否有这个值,如果有就会输出,没有则报错
'rain'
【小结】
在Python2.x中input对你输入的是什么格式它就把它当成什么格式来处理,例如你输入的是,你输入的是不加引号的,那就是变量,它就会按照变量去找变量值,你输入的是数字那就是数字,你输入的是带引号的那就是字符串,他就会按字符串的方式去处理
列表后续操作
>>> a = [1,2,3,'a','b']
>>> a.sort()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: str() < int() #字符串与整数不能排序
>>> a #通过切片,将123单独排序
[1, 2, 3, 'a', 'b']
>>> a[0:2]
[1, 2]
>>> a[0:3]
[1, 2, 3]
>>> a[1:4] #去1-4顾头不顾尾(包含索引的开头,不包含结尾)
[2, 3, 'a']
>>> a[-2:] #取后两个
['a', 'b']
>>>
>>> a[:3] #取前三个
[1, 2, 3]
>>>
extend (扩展操作)
>>> a = [1,2,3,4,5]
>>> b = ["a","b","c","d"]
>>> a + b
[1, 2, 3, 4, 5, 'a', 'b', 'c', 'd']
>>> a.extend(b)
>>> a
[1, 2, 3, 4, 5, 'a', 'b', 'c', 'd']
>>>
包含
>>> a = [1,2,3,4,5,"a","b""v"]
>>> a
[1, 2, 3, 4, 5, 'a', 'bv']
>>> 4 in a #4在a这个列表里吗?返回true表示在
True
>>> 7 in a #7在a这个列表里吗?返回false表示不在
False
>>>
元组
>>> t = (1,2,3,4,)
>>> type(t)
<class 'tuple'> #类型为元组
>>> dir(t) #可用的方法
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index']
>>> list(t) #转为列表
[1, 2, 3, 4]
>>> tuple(t) #转为元组
(1, 2, 3, 4,)
>>>
字典
#!/usr/bin/env python
# -*- coding:utf-8 -*-
'''
#dic = {'k1':'v1','k2':'v2'}
#字典的写法,写法一样的
#dic = dict(k1='v1',k2='v2')
例子1: fromkeys的用法,values与键值
#new_dict = dic.fromkeys(['k1','k2'],'v1')
#print(new_dict)
输出结果
{'k1': 'v1', 'k2': 'v1'}
#new_dict = dic.fromkeys(['k1','k2','k3'],'v1')
#print(new_dict)
输出结果
{'k1': 'v1', 'k2': 'v1', 'k3': 'v1'}
例子2:get的用法
#dic = dict(k1='v1',k2='v2')
print (dic['k1'])
print (dic['k2'])
print (dic['k3']) #键值k3不存在则会运行报错
print (dic['k3'])
KeyError: 'k3'
#print (dic.get('k1')) #dic.get这种方法就不会,如果不存在会默认一个NONE
#print (dic.get('k2'))
#print (dic.get('k3'))
#输出结果如下
#v1
#v2
#None
#也可以自己指定
#print (dic.get('k3','adair')) #指定的值不在就用adair表示
#直接会输出
#adair
例子3.keys,values.items的用法
#dic = {'k1':'v1','k2':'v2'}
print (dic.keys())
print (dic.values())
print (dic.items())
#输入结果如下
['k1', 'k1']
['v2', 'v2']
[('k2', 'v2'), ('k1', 'v1')]
#使用for循环打印
for k in dic.keys():
print(k)
for v in dic.values():
print(v)
for k,v in dic.items():
print(k,v)
#输出结果
k2
k1
v2
v2
('k2', 'v2')
('k1', 'v1')
例子4,pop方法,拿走一个,字典是无序的所以需要指定拿走什么
#dic = {'k1':'v1','k2':'v2'}
#dic.pop('k1')
#print(dic)
#输入结果为
#{'k2': 'v2'}
例子5,popitem方法 ,在python2中会删除最后一个键值对,在python3中删除无法确定
#dic = {'k1':'v1','k2':'v2'}
#dic.popitem()
#print (dic)
例子6,setdefault的用法,设置默认值,不设置默认为NONE
#dic = {'k1':'v1','k2':'v2'}
#dic.setdefault('k3')
#print(dic)
#update的用法,更新字典
#dic.update({'k3':123})
#print(dic)
'''
'''
练习:
有如下值集合 [11,22,33,44,55,66,77,88,99,90...],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中。
即: {'k1': 大于66 , 'k2': 小于等于66}
条件
上述集合的值需要放到
dic = {}
'''
'''
#实现方法1
all_list = [11,22,33,44,55,66,77,88,99,90]
dic = {}
l1 = []
l2 = []
for i in all_list:
if i >66:
l1.append(i)
else:
l2.append(i)
dic['k1'] = l1
dic['k2'] = l2
print (dic)
#输出结果
{'k2': [11, 22, 33, 44, 55, 66], 'k1': [77, 88, 99, 90]}
'''
'''
#实现方法2
#期望得到的结果{'k2': [11, 22, 33, 44, 55, 66], 'k1': [77, 88, 99, 90]}
dic = {}
all_list = [11,22,33,44,55,66,77,88,99,90]
for i in all_list:
if i>66:
if "k1" in dic.keys():
dic['k1'].append(i)
else:
dic['k1']=[i,]
else:
if "k2" in dic.keys():
dic['k2'].append(i)
else:
dic['k2']=[i,]
print(dic)
#输出内容
{'k2': [11, 22, 33, 44, 55, 66], 'k1': [77, 88, 99, 90]}
'''
集合
python的set和其他语言类似, 是一个无序不重复元素集, 基本功能包括关系测试和消除重复元素. 集合对象还支持union(联合), intersection(交), difference(差)和sysmmetric difference(对称差集)等数学运算.
sets 支持 x in set, len(set),和 for x in set。作为一个无序的集合,sets不记录元素位置或者插入点。因此,sets不支持 indexing, slicing, 或其它类序列(sequence-like)的操作。
下面来点简单的小例子说明把。
>>> x = set('spam')
>>> y = set(['h','a','m'])
>>> x, y
(set(['a', 'p', 's', 'm']), set(['a', 'h', 'm']))
再来些小应用。
>>> x & y #交集
set(['a', 'm'])
>>> x | y #并集
set(['a', 'p', 's', 'h', 'm'])
>>> x - y #差集
set(['p', 's'])
记得以前个网友提问怎么去除海量列表里重复元素,用hash来解决也行,只不过感觉在性能上不是很高,用set解决还是很不错的,示例如下:
>>> a = [11,22,33,44,11,22]
>>> b = set(a)
>>> b
set([33, 11, 44, 22])
>>> c = [i for i in b]
>>> c
[33, 11, 44, 22]
很酷把,几行就可以搞定。
1.8 集合
集合用于包含一组无序的对象。要创建集合,可使用set()函数并像下面这样提供一系列的项:
s = set([3,5,9,10]) #创建一个数值集合
t = set("Hello") #创建一个唯一字符的集合
与列表和元组不同,集合是无序的,也无法通过数字进行索引。此外,集合中的元素不能重复。例如,如果检查前面代码中t集合的值,结果会是:
>>> t
set(['H', 'e', 'l', 'o'])
注意只出现了一个'l'。
集合支持一系列标准操作,包括并集、交集、差集和对称差集,例如:
a = t | s # t 和 s的并集
b = t & s # t 和 s的交集
c = t – s # 求差集(项在t中,但不在s中)
d = t ^ s # 对称差集(项在t或s中,但不会同时出现在二者中)
基本操作:
t.add('x') # 添加一项
s.update([10,37,42]) # 在s中添加多项
使用remove()可以删除一项:
t.remove('H')
len(s)
set 的长度
x in s
测试 x 是否是 s 的成员
x not in s
测试 x 是否不是 s 的成员
s.issubset(t)
s <= t
测试是否 s 中的每一个元素都在 t 中
s.issuperset(t)
s >= t
测试是否 t 中的每一个元素都在 s 中
s.union(t)
s | t
返回一个新的 set 包含 s 和 t 中的每一个元素
s.intersection(t)
s & t
返回一个新的 set 包含 s 和 t 中的公共元素
s.difference(t)
s - t
返回一个新的 set 包含 s 中有但是 t 中没有的元素
s.symmetric_difference(t)
s ^ t
返回一个新的 set 包含 s 和 t 中不重复的元素
s.copy()
返回 set “s”的一个浅复制
请注意:union(), intersection(), difference() 和 symmetric_difference() 的非运算符(non-operator,就是形如 s.union()这样的)版本将会接受任何 iterable 作为参数。相反,它们的运算符版本(operator based counterparts)要求参数必须是 sets。这样可以避免潜在的错误,如:为了更可读而使用 set('abc') & 'cbs' 来替代 set('abc').intersection('cbs')。从 2.3.1 版本中做的更改:以前所有参数都必须是 sets。
另外,Set 和 ImmutableSet 两者都支持 set 与 set 之间的比较。两个 sets 在也只有在这种情况下是相等的:每一个 set 中的元素都是另一个中的元素(二者互为subset)。一个 set 比另一个 set 小,只有在第一个 set 是第二个 set 的 subset 时(是一个 subset,但是并不相等)。一个 set 比另一个 set 打,只有在第一个 set 是第二个 set 的 superset 时(是一个 superset,但是并不相等)。
子 set 和相等比较并不产生完整的排序功能。例如:任意两个 sets 都不相等也不互为子 set,因此以下的运算都会返回 False:a<b, a==b, 或者a>b。因此,sets 不提供 __cmp__ 方法。
因为 sets 只定义了部分排序功能(subset 关系),list.sort() 方法的输出对于 sets 的列表没有定义。
运算符
运算结果
hash(s)
返回 s 的 hash 值
下面这个表列出了对于 Set 可用二对于 ImmutableSet 不可用的运算:
运算符(voperator)
等价于
运算结果
s.update(t)
s |= t
返回增加了 set “t”中元素后的 set “s”
s.intersection_update(t)
s &= t
返回只保留含有 set “t”中元素的 set “s”
s.difference_update(t)
s -= t
返回删除了 set “t”中含有的元素后的 set “s”
s.symmetric_difference_update(t)
s ^= t
返回含有 set “t”或者 set “s”中有而不是两者都有的元素的 set “s”
s.add(x)
向 set “s”中增加元素 x
s.remove(x)
从 set “s”中删除元素 x, 如果不存在则引发 KeyError
s.discard(x)
如果在 set “s”中存在元素 x, 则删除
s.pop()
删除并且返回 set “s”中的一个不确定的元素, 如果为空则引发 KeyError
s.clear()
删除 set “s”中的所有元素
请注意:非运算符版本的 update(), intersection_update(), difference_update()和symmetric_difference_update()将会接受任意 iterable 作为参数。从 2.3.1 版本做的更改:以前所有参数都必须是 sets。
还请注意:这个模块还包含一个 union_update() 方法,它是 update() 方法的一个别名。包含这个方法是为了向后兼容。程序员们应该多使用 update() 方法,因为这个方法也被内置的 set() 和 frozenset() 类型支持。
collections系列
Counter是对字典类型的补充,用于追踪值的出现次数。
ps:具备字典的所有功能 + 自己的功能