一 集合

集合是一个无序的,不重复的数据组合,它的主要两个特性:

  • 去重,把一个列表变成集合,就自动去重了
  • 关系测试,测试两组数据之前的交集、差集、并集等关系

1 列表、字典、集合、字符串判断一个元素是否在其中都是in或not in

2 创建集合

s = set([3,5,9,10])      #创建一个数值集合  
  
t = set("Hello")         #创建一个唯一字符的集合  

3 关系测试

list1=[1,3,5,7,9,0,1,3,9,11]
list2=set(list1)
list3=set([1,5,10])
#交集测试
print(list2.intersection(list3))
b = t & s          # t 和 s的交集

#并集
print(t.union(s))
a = t | s          # t 和 s的并集

#差集
print(t.difference(s))
c =t-s         # 求差集(项在t中,但不在s中)

#对称差集
print(t.symmetric_difference(s))
d = t ^ s          # 对称差集(项在t或s中,但不会同时出现在二者中)

#子集
print(t.issubset(s))

4  基本操作

#添加
t.add(7)            # 添加一项  
s.update([10,37,42])  # 在s中添加多项 

#删除
s.remove(7)
s.pop()#随意删除一项并返回该项

#测长度
len(s)

#判断是否在其中
t in s 
#测试 t 是否是 s 的成员 

t not in s 
#测试 t 是否不是 s 的成员 

s.issubset(t) 
s <= t 
#测试是否 s 中的每一个元素都在 t 中 

s.issuperset(t) 
s >= t 
#测试是否 t 中的每一个元素都在 s 中

s.copy() 
#返回 set “s”的一个浅复制

二 文件操作

对文件操作流程

  1. 打开文件,得到文件句柄并赋值给一个变量
  2. 通过句柄对文件进行操作
  3. 关闭文件 

 

1 打开文件

f=open("yy","r",encoding="utf-8")#以读模式打开yy文件且编码格式为utf-8

打开文件的模式有:

  • r,只读模式(默认)。
  • w,只写模式。【不可读;不存在则创建;存在则删除内容;】
  • a,追加模式。【可读;   不存在则创建;存在则只追加内容;】

"+" 表示可以同时读写某个文件

  • r+,可读写文件。【可读;以追加形式写】
  • w+,写读【创建一个文件再追加写】
  • a+,同a

"U"表示在读取时,可以将 \r \n \r\n自动转换成 \n (与 r 或 r+ 模式同使用)

  • rU
  • r+U

"b"表示处理二进制文件(如:FTP发送上传ISO镜像文件,linux可忽略,windows处理二进制文件时需标注)

  • rb
  • wb
  • ab

2 基本操作

(1) 读

data=f.read()#读所有,只读一遍,读到结尾了
data1=f.read(10)#读几个字符

data2=f.readline()#读一行

#一行一行读,内存中只保留一行,高效读
for line in f:
    print(line)

(2)  写

f=open("yy1",'w',encoding='utf-8')#只写模式。【不可读;不存在则创建;存在则删除内容;】
f.write("我爱北京")

f=open("yy1",'a',encoding='utf-8') #追加写
f.write("天安门")

(3) 文件修改

两种方式:

  • 打开文件,修改完,写到一个新文件
  • 像vim先将文件加载进内存,再修改,再写回原文件

这里用第一种方法:

#先打开两个文件
f=open("yy",'r',encoding='utf-8')
f_new=open("yy2",'w',encoding='utf-8')
#循环,找到需要修改的地方
for line in f:
    if "提高产品质量" in line:
        line = line.replace("提高产品质量", "提高yiyi的产品质量力")
    f_new.write(line)
f.close()
f_new.close()

(4)其他重要函数

print(f.tell())#看文件句柄所在指针

f.seek(0)#移回指针

print(f.encoding)#打印文件编码

print(f.name)#打印文件名

print(f.readable())#判断文件是否可读

print(f.writable())#判断文件是否可写

f.flush()#刷新

3  打印缓冲进度条

import sys,time
for i in range(20):
    sys.stdout.write("#")
    sys.stdout.flush()
    time.sleep(0.1)

with语句

作用:避免打开文件后忘记关闭

举个栗子:

with open("yy",'r',encoding='utf-8') as f:
    for line in f:
        print(line)
#with结束后内部自动关闭并释放资源

在Python 2.7 后,with又支持同时对多个文件的上下文进行管理,即:

with open('log1') as obj1, open('log2') as obj2:
    pass

三 字符编码与转码

不同编码先转成Unicode再转成别的编码,Python3默认即为Unicode

详细文章:

http://www.cnblogs.com/yuanchenqi/articles/5956943.html

http://www.diveintopython3.net/strings.html

1 打印系统默认编码

import sys
print(sys.getdefaultencoding())

需知:

  • 在python2默认编码是ASCII, python3里默认是unicode
  • unicode 分为 utf-32(占4个字节),utf-16(占两个字节),utf-8(占1-4个字节), so utf-16就是现在最常用的unicode版本, 不过在文件里存的还是utf-8,因为utf8省空间
  • 在py3中encode,在转码的同时还会把string 变成bytes类型,decode在解码的同时还会把bytes变回string

上图仅适用于py2

2 in Python2

#-*-coding:utf-8-*-
__author__ = 'Alex Li'

import sys
print(sys.getdefaultencoding())


msg = "我爱北京天安门"
msg_gb2312 = msg.decode("utf-8").encode("gb2312")  #先用decode函数,指定原字符串的编码,将其解码成Unicode;再用encode函数指定将其转为何种编码
gb2312_to_gbk = msg_gb2312.decode("gbk").encode("gbk")

print(msg)
print(msg_gb2312)
print(gb2312_to_gbk)

in python2

 

3 in Python3

#-*-coding:gb2312 -*-   #这个也可以去掉
__author__ = 'Alex Li'

import sys
print(sys.getdefaultencoding())


msg = "我爱北京天安门"
#msg_gb2312 = msg.decode("utf-8").encode("gb2312")
msg_gb2312 = msg.encode("gb2312") #默认就是unicode,不用再decode,喜大普奔
gb2312_to_unicode = msg_gb2312.decode("gb2312")
gb2312_to_utf8 = msg_gb2312.decode("gb2312").encode("utf-8")

print(msg)
print(msg_gb2312)
print(gb2312_to_unicode)
print(gb2312_to_utf8)

in python3

 

四  函数

定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可

特性:

  • 减少重复代码
  • 使程序变的可扩展
  • 使程序变得易维护

1 语法定义

def sayhi():#函数名
    print("Hello, I'm nobody!")
 
sayhi() #调用函数

可以带参数

#下面这段代码
a,b = 5,8
c = a**b
print(c)
 
 
#改成用函数写
def calc(x,y):
    res = x**y
    return res #返回函数执行结果
 
c = calc(a,b) #结果赋值给c变量
print(c)

2 返回值

def test3():
    print("in the test3")
    return 1,"hello",["yii","alex"],{"name":"yiyi"}#可以返回数字,字符串,列表,字典等
z=test3()
print(z)
#输出结果为:
in the test3
(1, 'hello', ['yii', 'alex'], {'name': 'yiyi'})

返回值数=0:返回none

返回值数=1:返回object(Python所有数据类型都是对象)

返回值数>1:返回tuple(元组)

想获取函数的执行结果,就可以用return语句把结果返回

注意:

  1. 函数在执行过程中只要遇到return语句,就会停止执行并返回结果,so 也可以理解为 return 语句代表着函数的结束
  2. 如果未在函数中指定return,那这个函数的返回值为None 

3 调用

def test(x,y):
    print(x)
    print(y)
test(1,2)#位置参数调用,与形参一一对应
test(y=2,x=1)#关键字调用,与形参顺序无关
test(3,y=2)#既有位置参数调用,又有关键字调用,注意关键字参数不能写到位置参数前边

4  默认参数

特点:调用函数的时候,默认参数非必须传递

def test(x,y=2):
    print(x)
    print(y)
test(1)#y默认2
test(3,5)

非固定参数

实参不固定定义形参

(1) 非固定参数,*代表args接收参数不固定,接收几个位置参数转化为元组的方式

def test(*args):
    print(args)
test(1,3,4,6)#传值方式1,输出:将多个实参放到一个元组里
test(*[1,4,6])#传值方式2,args=tuple([1,4,6])变为元组

(2) 既有位置参数又有非固定参数

def test(x,*args):
    print(x)
    print(args)
test(1,3,4,6)#传值方式1,输出:
        #1
#(3, 4, 6),将多个实参放到一个元组里 test(*[1,4,6])#传值方式2,args=tuple([1,4,6])变为元组

 

(3) **kwargs,把n个关键字参数转化为字典方式

def test2(**kwargs):
    print(kwargs)
test2(name="yiyi",age=18)#传值方式1,输出{'age': 18, 'name': 'yiyi'}
test2(**{'name':'yiyi','age':18})#传值方式2

 

(4)既有位置参数又有非固定参数

def test3(name,**kwargs):
    print(name)
    print(kwargs)
test3('yiyi')#传值方式1,输出yiyi
                            #{}
test3("yiyi",age='18',sex='m')#传值方式2,输出yiyi
                              #{'sex': 'm', 'age': '18'}

(5)既有位置参数,又有默认参数,还有*args以及**kwargs

def test4(name,age=18,*args,**kwargs):
    print(name)
    print(age)
    print(args)
    print(kwargs)
test4('yiyi',age=16,sex='m',hobby='tesla')#输出yiyi
                                          # 16
                                          # ()
                                          # {'sex': 'm', 'hobby': 'tesla'}            

6全局与局部变量

(1)局部变量 

name = "Alex Li"
 
def change_name(name):
    print("before change:",name)
    name = "金角大王,一个有Tesla的男人"
    print("after change", name)
 
 
change_name(name)
 
print("在外面看看name改了么?",name)

输出:

before change: Alex Li
after change 金角大王,一个有Tesla的男人
在外面看看name改了么? Alex Li
  • 想在局部中改全局变量在局部中用global关键字

  • 字符串、整数不能直接在函数里改变,但列表、字典、集合、类可以改

(2)全局与局部变量

在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。
全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。
当全局变量与局部变量同名时:
在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用。

7 递归

一个函数在内部调用自身本身,这个函数就是递归函数。

def calc(n):
    print(n)
    if int(n/2) ==0:
        return n
    return calc(int(n/2))
 
calc(10)
 
输出:
10
5
2
1

递归特性:

  •  必须有一个明确的结束条件
  • 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
  • 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)
  • 堆栈扫盲http://www.cnblogs.com/lln7777/archive/2012/03/14/2396164.html 

8 高阶函数

一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。

1 def add(a,b,f):
2     return f(a)+f(b)
3 res=add(3,-5,abs)
4 print(res)