集合set
1.set集合用法1:
list1 = [1,2,3,3,4,4,5]
list1 = set(list1)
print(list1,type(list1))
#############################
{1, 2, 3, 4, 5} <class 'set'>
注:以上set的作用是将列表中重复的值只出现一遍,set在Python中单独的一种数据类型set,而且集合也是无序的!
2.set集合用法2:
list1 = set([1,2,3,4,5])
list2 = set([2,3,4,5])
print(list1.intersection(list2))
####################################
{2, 3, 4, 5}
注:输出交集
3.set集合用法3:
list1 = set([1,2,3,4,5])
list2 = set([2,3,4,5])
print(list1.union(list2))
############################
{1, 2, 3, 4, 5}
注:输出两个set数据的并集部分
4.set集合用法4:
list1 = set([1,2,3,4,5])
list2 = set([2,3,4,5])
print(list1.difference(list2))
#############################
{1}
注:输出两端set的差异部分,即在1中有2中没有的内容
5.set集合用法5:
list1 = set([1,2,3,4])
list2 = set([3,4])
print(list1.issuperset(list2))
################################
True
注:判断list1是否是list2的父集,即list2的内容是否是list1中都有的,反之issubset是子集的意思
6.set集合用法6:
list1 = set([1,2,3])
list2 = set([2,3,4])
print(list1.symmetric_difference(list2))
########################################
{1, 4}
注:输出两端set都没有出现重复的部分,也叫对称差集
7.set集合用法7:
list1 = set([1,2,3])
list2 = set([4,5,6])
print(list1.isdisjoint(list2))
###############################
True
注:判断两端set是否没有任何交集,即重复的部分
8.set集合用法8:
list1 = set([1,2,3])
list2 = set([2,3,4])
print(list1 & list2)
#########################
{2, 3}
注:&符号表示交集
9.set集合用法9:
list1 = set([1,2,3])
list2 = set([2,3,4])
print(list1 | list2)
#############################
{1, 2, 3, 4}
注:符号|表示并集
10.set集合用法10:
list1 = set([1,2,3])
list2 = set([2,3,4])
print(list1 - list2)
############################
{1}
注:符号-表示差集,即在list1中不在list2的内容
11.set集合用法11:
list1 = set([1,2,3])
list2 = set([2,3,4])
print(list1 ^ list2)
###########################
{1, 4}
注:符号^表示对称差集
12.set集合用法12:
list1 = set([1,2,3])
list1.add(999)
print(list1)
########################
{1, 2, 3, 999}
注:set集合添加内容
13.set集合用法13:
list1 = set([1,2,3])
list1.update([11,22,33])
print(list1)
#######################
{1, 2, 3, 33, 11, 22}
注:update方法添加多value在set集合中
14.set集合用法14:
list1 = set([1,2,3,2])
list1.remove(2)
print(list1)
#########################
{1, 3}
注:集合remove(默认将重复的也一并删除)
15.set集合用法15:
list1 = set([1,2,3,2,4])
print(len(list1))
#############################
4
注:输出set集合长度
16.set集合用法16:
list1 = set([1,2,3,2,4])
print(11 in list1)
########################
False
注:判断对象是否存在于set集合中
17.set集合用法17:
list1 = set([1,2,3,2,4])
list1.discard(2222)
print(list1)
######################
{1, 2, 3, 4}
注:同样是删除,但是discard和remove的区别是discard如果匹配的value是不存在的话程序不报错,但是remove就会报错
文件处理
1.文件打开:
data = open('initialize.py').read()
print(data)
#################
#!/bin/env python3
import os
print("Please setting your nic-ip-address.")
os.system("systemctl start NetworkManager.service")
nic_name = input("Please input your nic_name : ")
if nic_name == "eth0":
nic_name_delete = "nmcli connection delete " + nic_name
os.system(nic_name_delete)
judge_start = input("Would you want to continue ? 'y' or 'n' ")
if judge_start == "y":
nic_ipv4_address = input("Please input your ip_address and prefix,for example; 1.1.1.1/2
4 : ")
judge_gateway = input("Would you settings gateway? 'y' or 'n' : ")
if judge_gateway == "y":
nic_gateway = input("Please input your gateway;for example 1.1.1.254 ; ")
nic_settings = "nmcli connection add type ethernet con-name " + nic_name + " " + "ifn
ame " + nic_name +" " +" ip4 " + nic_ipv4_address +" " +" gw4 " + nic_gateway
os.system(nic_settings)
os.system("systemctl restart network")
judge_dns = input("Would you settings dns-server? 'y' or 'n' : ")
if judge_dns == "y":
nic_dns = input("Please input your dns-server-address : ")
nic_dns_setting = "nmcli connection modify " + nic_name + " ipv4.dns" + " " + nic
_dns
os.system(nic_dns_setting)
------------------------此处略过省略内容------------------------
2.文件打开:
>>> f = open('test')
>>> data1 = f.read()
>>> data2 = f.read()
>>> print(data1,data2)
test
test
test
test
test
test
test
注:为什么data2没有输出文件内容而是空白呢?原因是当内存读取data1的时候将文件内容输出,但是当data2也要继续读取文件内容时并没有从文件的第一行开始读取,而是接着data1的文件内容继续往下读,所以是空行
3.文件写:
[root@python3 day3]# cat test
test
test
test
test
test
test
test
[root@python3 day3]# python3
Python 3.4.5 (default, Nov 9 2016, 16:24:59)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> f = open('test','w')
>>> print(f)
<_io.TextIOWrapper name='test' mode='w' encoding='UTF-8'>
>>> exit()
[root@python3 day3]# cat test
[root@python3 day3]# python3
Python 3.4.5 (default, Nov 9 2016, 16:24:59)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> f = open('test2','w')
>>> exit()
[root@python3 day3]# ls
test test2
[root@python3 day3]# cat test2
[root@python3 day3]#
注:在Python3中,如果针对文件处理想执行”写”操作,默认使用”r”方式是没办法写入的,就是这么无语,r只可以读,w只可以写,如果是”w”模式则不可以读取文件内容,如果w一个文件,这个文件名如果不存在默认会创建出这个文件,如果这个文件存在那么执行多次open w就会把这个文件的内容清空…就是这么恶心…
4.文件写2:
>>> f = open('test2','w')
>>> f.write("Charlie")
7
>>> f = open('test2','r')
>>> data = f.read()
>>> print(data)
Charlie
exit()
[root@python3 day3]# less test2
Charlie
注:写了就不能读,读了就不能写…
5.文件写入3:
[root@python3 day3]# less test2
Charlie
[root@python3 day3]# python3
Python 3.4.5 (default, Nov 9 2016, 16:24:59)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> f = open('test2','w')
>>> data = f
>>> data.write("hello")
5
>>> exit()
[root@python3 day3]# less test2
hello
[root@python3 day3]#
注:再次写入,内容不会追加,而是覆盖…尼玛蛋啊!!!
6.文件追加:
f = open('test2','a',encoding="UTF-8")
f.write("tandabin\n")
f.close()
f = open('test2','r')
data = f.read()
print(data)
f.close()
##########################
tandabin
tandabin
tandabin
tandabin
注:”a”代表追加的意思,每次文件打开最好手动加上关闭操作
7.文件读取readline:
f = open('test2','r',encoding="UTF-8")
for i in range(5):
print(f.readline())
###############################
1
2
3
4
注:readline默认只是读取一行,通过循环可以控制读取的行数
8.文件读取readlines:
f = open('test2','r',encoding="UTF-8")
print(type(f.readlines()))
######################################
<class 'list'>
f = open('test2','r',encoding="UTF-8")
print(f.readlines())
#######################################
['1\n', '2\n', '3\n', '4']
注:readlines每次只读取一行,且自动换行,默认输出数据类型是列表
9.文件读取readlines2:
f = open('test2','r',encoding="UTF-8")
for line in f.readlines():
print(line)
############################
1
2
3
4
注:由于readlines自动换行,结合for循环使用就可以做到换行打印输出内容
10.文件读取:
f = open('test2','r',encoding="UTF-8")
for line in f:
print(type(line))
#######################################
<class 'str'>
<class 'str'>
<class 'str'>
<class 'str'>
f = open('test2','r',encoding="UTF-8")
count = 0
for line in f:
print(line.strip())
#################################
1
2
3
4
注:不管是read还是readlines都是默认将文件的所有行内容从硬盘全部读取到内存中作处理,小文件的情况下倒是没有问题,但是如果处理的数据是庞大的话,那么这种逻辑运算对内存会做出极大的负荷,不管是一次性读取一行循环读取还是一次性读取全部,归根结底在内存都会累计记录所有行的内容,如果数据太大超出内存的负荷,那么就会出现程序崩溃,以上f:的用法就避免出现这种问题,每次循环处理输出一行内存之后在内存中就不在记录一段地址,delete掉内存再重新记录下一行的内容,作出逻辑处理再次输出到屏幕,这种方法不管是应对2G的数据文件还是20G的文件在内存中的负荷始终都只会一次记录一行的地址,占据一行的内存空间,从而极大的降低内存负荷
11.文件句柄:
f = open('test2','r',encoding="UTF-8")
print(f.tell())
print(f.read())
print(f.tell())
############################
0
aaa
3
注:tell输出文件句柄第一个,也就是0,在输出内容后,再次输出tell会根据文件字符数的最后一个继续往后输出,也就是3,道理和多次read文件内存后面是空白是同样的道理
12.光标控制:
f = open('test2','r',encoding="UTF-8")
print(f.tell())
print(f.readline())
print(f.readline())
print(f.readline())
print(f.tell())
f.seek(0)
print(f.readline())
###############################
0
aaa
bbb
ccc
15
aaa
注:seek的作用是控制文件打开后将光标(默认光标会停留在文件的最后一行)移动到第一行,再出输出readline会发现文件内容重新输出第一行
13.接口调用
f = open('test2','r',encoding="UTF-8")
print(f.fileno())
########################################
3
注:此方法很少用,但是要注意的是,fileeno是调出当前OS底层打开文件所调用的接口,在Python中,打开文件的这个动作并不是Python本身去完成,只是Python调用了系统底层专门拿来打开的接口去打开文件,同时这个接口也被其他语言所调用
14.磁盘刷新flush用法1
>>> f = open('test','w')
>>> f.write("a1\n")
3
>>> f.write("a2\n")
3
>>> f.write("a3\n")
3
##################################
Every 1.0s: less test Thu Dec 22 14:20:29 2016
#############################
>>> f.flush()
Every 1.0s: less test Thu Dec 22 14:20:50 2016
a1
a2
a3
注:flush用法是每次在文件中插入内容的时候实施将缓存区的文件往磁盘中写入,避免出现延迟的问题,因为默认在在进行文件写入处理的时候有一种机制,当有数据请求写入磁盘的时候为了避免造成磁盘效率没有内存高而造成的瓶颈问题,会优先把数据先写入内存中的部分缓存区域,待磁盘有负荷不高时再冲内存缓存区去取数据
15.flush用法2:
import sys
import time
for i in range(20):
sys.stdout.write("#")
sys.stdout.flush()
time.sleep(0.1)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
####################
注:换换输出进度条,利用flush方法刷新缓冲区
16.truncate字符截断
test2 = "123456789"
f = open('test2','a',encoding="UTF-8")
f.truncate(5)
########################
test2 = "12345"
注:从第五个字符5开始往后截断,故而处理后的字符是12345
17.以读取和追加方式处理文件:
f = open('test2','r+',encoding="UTF-8")
print(f.readline())
print(f.readline())
print(f.readline())
print(f.tell())
f.write("Charlie")
print(f.readline())
注:但是write的内容会在最后一行
18.以读取二进制文件方式打开文件:
f = open("test2",'rb',encoding="UTF-8")
print(f.readline())
########################
Traceback (most recent call last):
File "C:/Users/dabin/PycharmProjects/dabin/day3/set.py", line 3, in <module>
f = open("test2",'rb',encoding="UTF-8")
ValueError: binary mode doesn't take an encoding argument
f = open("test2",'rb')
print(f.readline())
##########################
b'12345\r\n'
注:以为UTF-8编码格式打开,报错很正常,取消即可正常输出
19.二进制写方式处理文件:
f = open("test2",'wb')
f.write("Hello,world!".encode())
f.close()
##################
test2 = "Hello,world!
20.文件修改:
test2 =
Hello,world!
1
2
3
f = open('test2','r',encoding="UTF-8")
f2 = open('test3','w',encoding="UTF-8")
for line in f:
if line.strip() == "2":
line = line.replace("2","22222")
f2.write(line)
f.close()
f2.close()
###############################
test2 =
Hello,world!
1
2
3
###############################
test3 =
Hello,world!
1
22222
3
注:个人觉得这种方法针对大文件绝对是作死,相当于把整套文件复制一遍,匹配修改的部分重新赋值然后对应的打印到新的文件中
21.文件修改导入外部变量:
[root@python3 day3]# cat amend.py
#!/usr/bin/env python3
f = open('test2','r',encoding="UTF-8")
f2 = open('test3','w',encoding="UTF-8")
import sys
one = sys.argv[1]
two = sys.argv[2]
for line in f:
if one in line:
line = line.replace(one,two)
f2.write(line)
f.close()
f2.close()
#######################
[root@python3 day3]# ./amend.py 2 23232323
[root@python3 day3]# cat test2
Hello,world!
1
2
3
a
[root@python3 day3]# cat test3
Hello,world!
1
23232323
3
a
[root@python3 day3]#
注:引入模块sys的方法argv,可以通过Python实现shell中的sed功能
22.with open用法:
with open('test2','r',encoding="UTF-8") as f:
for line in f:
print(line.strip())
###################################
Hello,world!
1
2
3
注:with open用法和open类似,只是当with open语句执行完后会自动关闭文件
23.with open打开多个文件:
with open('test2','r',encoding="UTF-8") as f,\
open('test3','r',encoding="UTF-8") as f2:
for line in f:
print("f1",line.strip())
for line2 in f2:
print("f2",line2.strip())
#######################################
f1 Hello,world!
f1 1
f1 2
f1 3
f2 1
f2 2
f2 3
f2 3
f2 3
f2 3
f2 3
f2 3
注:Python官方的解释中,建议一行代码的字符数不超过80个,所以考虑到这一点,当一行代码数多时,需要使用”\”进行换行
24.字符编码转换:
#-*-coding:gbk-*-
s = "皇马"
print(s.encode("gbk"))##因为已经事先是万国码,所以直接解码成gbk,又由于转换之后是byte类型,所以会显示编码格式
print(s.encode("utf-8").decode("utf-8").encode("gb2312").decode("gb2312"))##最后一次转换成字符串
注:不管是在Python2还是Python3中,不同的字符编码之间的转换都必须经过Unicode;如果是UTF-8想转换成GBK,必须从UTF-8decode(加码)成Unicode,然后声明给Unicode原来是什么编码格式,然后再解码encode成你想要的编码格式GBK
25.过程以及过程:
def func1():
"""test1"""
print("test1")
return 0
def func2():
"""test2"""
print("test2")
x = func1()
print(x)
y = func2()
print(y)
#############################
test1
0
test2
None
注:在Python中,过程只是没有返回值的函数,但是一旦程序执行完后Python依然会给过程赋予一个返回值“none”,所以在Python中过程和函数的区别其实没有很大的界限;至于什么是面向过程?则是把一段代码的逻辑包含在def xxx关键字下,但在主代码需要调用这段功能的时候则只需要调用这段编辑好的def过程就可以了
26.函数式编程:
import time
def log():
time_format = "%Y-%m-%d %X"
time_current = time.strftime(time_format)
with open('logfile','a+') as f:
f.write("%s : test\n"% time_current)
def test1():
print("test1")
log()
def test2():
print("test2")
log()
def test3():
print("test3")
log()
test1()
test2()
test3()
################################
test1
test2
test3
logfile=
2016-12-25 14:33:37 : test
2016-12-25 14:33:37 : test
2016-12-25 14:33:37 : test
2016-12-25 14:33:38 : test
2016-12-25 14:33:38 : test
2016-12-25 14:33:38 : test
注:函数式编程,将一段逻辑写成过程(也叫函数,只是返回值是none),然后多次调用,实现代码复用,保持一致性以及非常重要的可扩展性
27.函数返回值:
def test1():
print('test1')
def test2():
print('test2')
return 0
def test3():
print("test3")
return 1,"Charlie",['charlie',11,'CR7'],{"name":"800820880"}
x=test1()
y=test2()
z=test3()
print(x)
print(y)
print(z)
############################
**test1
test2
test3
None
0
(1, 'Charlie', ['charlie', 11, 'CR7'], {'name': '800820880'})
注:如果没有返回值,那么返回none,返回书等于1,那么返回object,在Python中,所有的数据类型都是对象,返回数大于1,那么返回tuple(元组),要注意的是,原则上return数据只能返回一个数,但是在Python中如果出现return多个数据,那么会以元组的形式返回,从视觉上感觉好像是多分数据,其实实际上还是一份,值得注意的是,为什么函数需要有返回值?那是因为考虑到后面的程序可以需要获取函数不同的返回值去执行不同的逻辑判断或者不同的操作,所以函数需要返回值的存在。
28.带参数的函数:
def test(x,y):
print(x,y)
test(1,2)
#####################
1 2
###########################
def test(x,y):
print(x,y)
test(y=1,x=123)
#######################
123 1
注:x,y称之为形式参数,1,2称之为实际参数,而且形参和实参必须一一对应,以及个数相同,但是如果需要不确定位置,想自己定义顺序,就必须用下一种方法定义参数;一种是位置参数调用,一种是关键字参数调用,但是注意的是,强烈不建议位置参数和关键字参数混合使用,如果这么做,那么关键字参数永远不可以在位置参数前面!
29.默认参数:
def test(x,y=1):
print(x,y)
test(1231231)
########################
1231231 1
########################
def test(x,y=1):
print(x,y)
test(12312312,y=555555555555555)
##################################
12312312 555555555555555
注:以下这件用法就是设定一个y的默认值,但是允许用户调用函数的时候赋予y新的值然后输出,这种用法主要的应用场景是软件安装的默认路径以及自定义路径,或者数据库的默认链接,端口号等等
30.参数组:
def test(*group):
print(group)
test(1,2,2,2,2,1,1,1,1,1,1,1)
#################################
(1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1)
注:以”*”开头的形参,可以接受多个不固定数量的实参,然后以元组的方式保存下来
31.参数组2:
def test(x,*charlie):
print(x)
print(charlie)
test(1,2,3,4,1,1,1,1,1,1,1)
################################
1
(2, 3, 4, 1, 1, 1, 1, 1, 1, 1)
注:参数组还可以这么使用,这么做就定义了除了X之外的实际参数数量可以无限扩大
32.参数组传列表:
def test3(*args):
print(args[0])
test3([1,2,3,4])
test3(*[1,2,3,4])
#############################
[1, 2, 3, 4]
1
注:列表带☆传入,是把列表的每个值取出然后变成了元组;列表不带☆的话是以列表整体为一个值传入元组,整体输出
33.参数组字典:
def test3(**kwargs):
print(kwargs['sex'])
print(kwargs)
test3(name='charlie',age=22,sex='man')
test3(**{
'name':'charlie',
'sex':'man',
'age':23,
})
######################################
man
{'age': 22, 'sex': 'man', 'name': 'charlie'}
man
{'age': 23, 'name': 'charlie', 'sex': 'man'}
注:字典传入函数的用法,必须使用☆号引用字典
34.字典默认参数混合使用:
def test5(name,age=18,**kwargs):
print("姓名: ",name)
print("年龄: ",age)
print(kwargs)
test5('charlie',age=20,sex='M',hobby='Football')
test5('charlie',age=20,**{'sex':'m','hobby':'football'})
#########################################################
姓名: charlie
年龄: 20
{'sex': 'M', 'hobby': 'Football'}
姓名: charlie
年龄: 20
{'sex': 'm', 'hobby': 'football'}
注:要注意默认参数的赋值方式,要么使用关键字调用要么使用位置参数调用
35.函数组混合使用:
def test10(name,age=11,*args,**kwargs):
print(name)
print(age)
print(args)
print(kwargs)
test10('charlie',20,7,7,7,7,7,7,hobby='Football',sex='M')
###########################################################
charlie
20
(7, 7, 7, 7, 7, 7)
{'sex': 'M', 'hobby': 'Football'}
注:☆args只接受位置N个参数转换成元组,☆☆kwargs只接受关键字N个参数转换成字典的方式
36.全局变量,局部变量,作用域:
sex='m'
def changename(name):
global sex
sex='wm'
age = 22
print(age)
print(sex)
print(name)
changename('charlie')
################################
22
wm
charlie
注:如果要定义全局变量,在函数的开头最顶行定义,在函数中也可以直接调用变量,但是不可以修改全局变量的值,如果需要修改,则需要声明全局变量global,然后才可以修改;另外在函数中定义的变量属于局部变量,在函数外是无法获取值的,而且函数就是在函数中定义的变量的作用域,但是需要注意,强烈不建议在函数中定义全局变量的值,因为一旦程序代码越来越多,每当程序在某处调用函数,发现引用了全局变量,会频繁的跳回程序首行,而且一旦程序出错,根本不知道是在程序的哪个位置调用函数时全局变量被修改了,所以如果需要需要修改全局变量,那么最好是在函数外头定义了全部变量的值,然后在函数中通过global声明全局变量,然后作出修改
37.全局变量2:
names = ['charlie','tom','peter']
def test():
names[0] = 'bob'
print("inside: ",names)
test()
print(names)
#####################################
inside: ['bob', 'tom', 'peter']
['bob', 'tom', 'peter']
注:除了数字以及字符之外,稍微复杂的数据类型(list,dic,set)都是可以在函数中局部变量修改全局变量的
38.递归:
def digui(n):
print(n)
digui(n+1)
digui(0)
#####################
1
2
3
...
997
error....
注:递归函数必须有一个明确的结束条件,而且每次进入深层次的递归,问题规模相比上次递归都应该有所减少,再者递归效率不高,递归次数过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会参加一层栈帧,每当函数返回,就会减少一个栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,就会导致栈溢出)
39.递归用法2:
def max(n):
print(n)
if int(n/2) > 0 :
return max(int (n/2))
print(">>>>",n)
max(10)
#######################
10
5
2
1
>>>> 1
注:有效控制递归的次数
40.高阶函数:
def shuxue(a,b,c):
res = c(a)+c(b)
print(res)
shuxue(1,-19,abs)
##########################
20
注:将一个函数作为一个参数传入另外一个函数进行逻辑处理