Long Way To Go 之 Python 3

集合set

        集合是无序的

 

作用:1.去重           eg. 把list转成set可自动去重

         2.关系测试     eg. 交集、并集、差集等

                             举个栗子:Python班有个名字列表1,Linux班有个名字列表2,但是现在有人报了两个班,想计算出报名的总人数

                                            ——> 可用集合删除重复数据

 

                                           如果不用集合,用现已知的知识

                                           ——> 创建一个空list

                                                     for循环(已有的包含重复名的list)

                                                     每一次循环元素,就扔到空列表里,但是要先判断元素是否已经在空list里存在

 

操作操作~~~

基本:

 

# define set
list_1 = [1,4,5,7,3,6,7,9]
list_1 =set(list_1)   # 大括号,有点像字典,但是不是字典

list_2 = set([2,6,0,66,22,8,4])
print(list_1,list_2)


# intersection交集
print(list_1.intersection(list_2))


# union并集
print(list_1.union(list_2))


# difference差集
print(list_1.difference(list_2))  # in list 1 but not in list 2
print(list_2.difference(list_1))  # in list 2 but not in list 1


# subset子集
print(list_1.issubset(list_2))


# superset 超集
print(list_1.issuperset(list_2))


list_3 = set([1,3,7])
print(list_3.issubset(list_1))
print(list_1.issuperset(list_3))


# 对称差集
print(list_1.symmetric_difference(list_2)) # 互相都没的取出来了



# 判断交集
list_4 = set([5,6,8,7])
print(list_3.isdisjoint(list_4))  # return True if two sets have a null intersection
View Code

 

运算符:

# 交集
print(list_1 & list_2)
# 并集
print(list_2 | list_1)
# 差集
print(list_1 - list_2)   # 在1中不在2
# 对称差价
print(list_1 ^ list_2)  # 互相重复的去掉,取剩下的
View Code

增删:

# 增 add      集合没有insert,只有add
list_1.add(99)     # add one element
list_1.update([888,777])  # add more elements


# 删 remove
list_1.remove(99)

# 另外两个删除方法:pop  &  discard
list_1.pop()  #remove and return an arbitrary set element
list_1.discard(999) ## remove an element from a set if it is a member, if the element is not in the set, do nothing



# 判断 element x 在不在set s 里面
x in s
x not in s


# set s 的长度
len(s)  
View Code

浅copy:

list_1.copy()

 

 

文件:

文件操作流程:

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

操作操作~~

基本1:

# normal way
f = open("yesterday","a",encoding="utf=8") 
data = f.read()    # 只读
print("---read----",data)
f.close()  # 关闭文件


# using "with": close file automatically
with open("yesterday","r",encoding = "utf-8") as f:  #     相当于 f = open("yesterday","r",encoding = "utf-8")
     for line in f:
          print(line)

# open multiple files
with open("o1") as obj1,\
     open("o2") as obj2:

ps: windows 打开文件,默认是GBK,但是Python默认处理编码是UTF-8,但是UTF-8 不能处理GBK,所以要用UTF-8来打开文件

 

另外,打开文件的模式:

          r : 只读(如果不写模式,默认是r)

          w : 只写(只可写,如果文件不存在则创建,如果存在就会覆盖原内容)

          a : 追加(可读可写,如果文件不存在则创建,如果存在就追加)   ps: 只能追加到最后

升级版模式:

         r+ :  读写(可读可写可追加)

         w+ :写读(并没什么卵用)

         a+ : 同a

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

         rU

         r+U

处理二进制文件时:(eg.视频文件)

         rb 

         wb

         ab

         二进制文件不是说文件内容变成0110001这种形式,而是文件是以二进制编码储存的

 

基本2:

#只读前五行
for i in range(5):
    print(f.readline())

# 假如文件内存很大,f.readlines只适合读小文件
# 可以读一行,但是不存在内存里,内存里只保存一行;就是循坏一行,删掉一行
count = 0 # 文件不是列表了,变成了迭代器
for line in f:
    if count == 9:
        print("---------我是分割线----------")
        count += 1
        continue
    print(line)
    count += 1


# tell & seek
print(f.tell())    # tell是按照已读的字符来计数的
f.seek(0)  # 光标回到第二行,回不去,只能回到0
print(f.tell())   # return 0
f.seek(10) #  从第十个字母开始


print(f.flush()) # 刷新
# 以写的模式,打开文件,写完一行就默认写到硬盘上了,但是其实不一定;
# 刚写完一行,然后突然断电,这一行就可能没写进去
# 所以现在,每写一行,会暂时存在内存的缓存里,等缓存大小满了,就一次性刷到硬盘上,有可能会好几行一起写到硬盘


# truncate
f = open("yesterday","a",encoding="utf=8")
#f.truncate()  # 文件清空   在w模式下
f.seek(10)   #在这里,移动不好使
f.truncate(20)   # 从文件开头第20个字母开始截断
View Code

文件修改:

with open("yesterday","r",encoding = "utf-8") as f,\
      open("yesterday.bak","w",encoding = "utf-8") as f_new:
      for line in f:
          if "肆意的快乐" in line:
             line = line.replace("肆意的快乐等我享受","肆意的快乐等alex享受")
          f_new.write(line)



# 输入参数,再替换
import sys
with open("yesterday","r",encoding = "utf-8") as f,\
      open("yesterday.bak","w",encoding = "utf-8") as f_new:
      find_str = sys.argv[1]
      replace_str = sys.argv[2]
      for line in f:
          if find_str in line:
             line = line.replace(find_str,replace_str)
          f_new.write(line)
View Code

 

字符编码

需知:

1.在python2默认编码是ASCII, python3里默认是unicode

2.unicode 分为 utf-32(占4个字节),utf-16(占两个字节),utf-8(占1-4个字节), so utf-16就是现在最常用的unicode版本, 不过在文件里存的还是utf-8,因为utf8省空间

3.在py3中encode,在转码的同时还会把string 变成bytes类型,decode在解码的同时还会把bytes变回string

 

转码流程:(其他转码也是通过和unicode的encode/decode来操作)

 

pyhton2:

         如果文件头声明了#_*_coding:utf-8 _*_,就可以写中文了,然后以下代码都是utf-8的格式; 如果不声明,python在处理这段代码时按ASCII,然后会报错。

#_*_coding:utf-8 _*_

s = “你好”   #你好这个字符是utf-8格式
s = u"你好”  # 你好这个字符就是unicode格式

# utf-8 转成 gbk
s_to_gbk = s.decode("utf-8").encode("gbk")

 

python3:

     默认的文件编码是utf-8,可以直接写中文,也不需要文件头声明编码了。

# utf 转 gbk
s = “你好”  #变量默认是unicode编码,不是utf-8,所以转换时不用解码
print(s.encode("gbk")) # 直接encode成gbk
# 但是print出来是没有显示中文的,因为文件编码是utf-8

 

改一下~~

# _*_ coding: gbk _*_
# 改的只是文件编码,但是python3里还是默认的unicode

s = "你好" # 是个unicode,所以没有s.decode()操作
print(s.encode("gbk"))
#现在print出来是gbk了,但是显示也不是中文,是因为显示的是bytes类型

 

 

 

函数

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

 

why 函数?

  1. 减少重复代码
  2. 使程序变的可扩展
  3. 使程序变得易维护

 

1.定义:

# define a function 函数
def func1():   # 函数名,空号内可定义参数
    """testing1"""   # 文档描述,强烈建议写上
    print("in the func1") # 函数体
    return 0   

# define a progress 过程
def func2():
    """testing2"""
    print("in the func2")

#调用函数
x = func1()  # x 是接收func1的返回值
y = func2()  # 返回none

带参数定义:

def calc(x,y):
    res = x**y
    return res #返回函数执行结果
 
c = calc(a,b) #结果赋值给c变量
print(c)

嵌套式函数:

name = "Alex"

def change_name():
    name = "Alex2"

    def change_name2():
        name = "Alex3"
        print("第3层打印",name)

    change_name2() #调用内层函数
    print("第2层打印",name)


change_name()
print("最外层打印",name)
View Code

 

 

2.参数:

a) 形参和实参:

 

b)默认参数

    默认参数特点:  调用函数的时候,默认参数可有可无(非必须传递)
用途:(比如一键安装)默认安装值

IMPORTANR ! 关键参数必须放在位置参数之后 (关键参数就是默认参数,位置参数如上图xyab)
def test(x,y=2): # 默认参数
      print(x)
      print(y)
test(1)   # print出来是1  2
test(1,y=3)  # print出来是1  3

 

c) 关键参数(参照b))

d) 非固定参数

        函数在定义时不确定用户想传入多少个参数,就可以使用非固定参数

eg.1

def stu_register(name,age,*args): # *args 会把多传入的参数变成一个元组形式
    print(name,age,args)
 
stu_register("Alex",22)
#输出
#Alex 22 () #后面这个()就是args,只是因为没传值,所以为空
 
stu_register("Jack",32,"CN","Python")
#输出
# Jack 32 ('CN', 'Python')

eg.2

# 不传递元组,传递字典
# **kwargs : 把n个关键字参数,转化成字典的方式

def test2(**kwargs):
    print(kwargs)

test2(name="alex",age=8,sex="F")
# 输出
#{'name': 'alex', 'age': 8, 'sex': 'F'}

eg.3

def test3(name,age=18,*args,**kwargs): # 一个位置参数,一个默认参数
    #默认参数一定要放在参数组前面,参数组一定要往后放
    print(name)
    print(age)
    print(args)
    print(kwargs)

test3("alex",age = 34, sex ="m",hobby = "tesla")
# 全给字典了
# *args 不能接受关键字,只接受位置参数,所以是空的元组

# 输出
alex
34
()
{'sex': 'm', 'hobby': 'tesla'}

 

3.局部变量

def change_name(name):
    print("before change",name)
    name = "Alex Li"  # 局部变量,只在函数里有效,这个函数就是这个变量的作用域
    print("after change",name)
name = "alex"
change_name(name)
print(name)   # 还是alex, Alex 只是局部变量

#输出
#before change alex
#after change Alex Li
#alex
View Code

 

4.全局变量

school = "Oldboy edu." # 全局变量
def change_name(name):
    school = "Mage Linux"
    print("before change",name,school)
    name = "Alex Li"
    print("after change",name)

print(school)
name = "alex"
change_name(name)
print(name)   # 还是alex, Alex 只是局部变量
print(school)

#输出
#Oldboy edu.
#before change alex Mage Linux
#after change Alex Li
#alex
#Oldboy edu.
View Code

 

5.返回值

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

注意:

  1. 函数在执行过程中只要遇到return语句,就会停止执行并返回结果,so 也可以理解为 return 语句代表着函数的结束
  2. 如果未在函数中指定return,那这个函数的返回值为None 
  3. 如果return多个值,就全部会包含在元组中
  4. retrun的值可以是个数,也可以是字符串、列表、字典等

 

6.递归

     在函数内部,可以调用其他函数。如果调用的是本身,这个函数就是递归函数。

特点:   

    1. 必须有一个明确的结束条件

    2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少

    3. 递归效率不高,如果递归调用的次数过多,会导致栈溢出

def calc(n):
    print(n)
    if int(n/2) > 0:
       return calc(int(n/2))
    print("---->",n)

calc(10)

#输入
#10
#5
#2
#1
#----> 1
View Code

 

7.匿名函数

#这段代码
def calc(n):
    return n**n
print(calc(10))
 
#换成匿名函数
calc = lambda n:n**n
print(calc(10))

#匿名函数主要是和其它函数搭配使用的
res = map(lambda x:x**2,[1,5,7,4,8])
for i in res:
    print(i)

#输出
#1
#25
#49
#16
#64
View Code

 

8.函数式编程

         "函数式编程"是一种“编程范式”(programming paradigm),也就是如何编写程序的方法论。主要思想是把运算过程尽量写成一系列嵌套的函数调用。

 

9.高阶函数

       变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。

# 普通函数
def add(a,b):  # 算一个加法
    return  a+b


# 高阶函数
def add(a,b,f):
    return f(a)+f(b)

res = add(3,-6,abs)  # abs 本身就是个函数 absolute
print(res)

 

附加~~~~~·

简易进度条:

import sys,time

# 一个一个蹦出来
for i in range(20):
    sys.stdout.write("#")
    sys.stdout.flush()
    time.sleep(0.1)

 

posted @ 2017-04-26 18:41  来一打烧饼  阅读(167)  评论(0编辑  收藏  举报