set特性:无序,不重复,可嵌套
创建set
set_example = set("123", "213", "234", "432")
s1 = [11,22,33,44,11,22,33]
s2 = set(s1)
print(s2)
list()相当于执行构造方法__int__,内部会执行一个for循环,循环(11,22,33,44,11,22,33)set差异
s1 = {11, 33, 44, 66}
s2 = {22, 33, 44 ,55, 88}
s1中存在s2中不存在
s3 = s1.difference(s2)
print(s3)
差异结果更新到s1中
s1.difference_update(s2)
print(s1)
s1.symmetric_difference_update(s2)print(s1)
移除指定元素,存在移除,不存在不做任何操作,discard最有用
s1.discard(11)
print(s1)
移除指定元素,不存在报错
s1.remove(11111)
随机移除
s1 = {11, 33, 44, 66}
s3 = s1.pop()
print(s1)
print(s3)
交集
s3 = s1.intersection(s2)
print(s3)
交集更新到s1
s1.intersection_update(s2)
print(s1)
是否父子序列
s1.issubset(s2)
s1.issuperset(s2)
并集
s3 = s1.union(s2)
print(s3)
循环更新(字符串、列表、元组)即可以for循环的对象
s1.update([11,22,33,44,55,66,77,88,99,00])
print(s1)
set练习题
old_dict = {
"#1": 8,
"#2": 4,
"#4": 2,
}
new_dict = {
"#1": 4,
"#2": 4,
"#3": 2,
}
#应该删除哪几个槽位
old_set = set(old_dict.keys())
new_set = set(new_dict.keys())
old_set.difference()
#需要删除的,old中有new中没有
remove_set = old_set.difference(new_set)
print("需要删除的槽位:%s" % remove_set)
#需要增加的,new中有old没有
add_set = new_set.difference(old_set)
print("需要增加的槽位:%s" % add_set)
#需要更新的,old和new的交集
update_set = old_set.intersection(new_set)
print("需要更新的槽位:%s" % update_set)
函数定义
1.def关键字创建函数
2.函数名
3.()
4.函数体
5.返回值
6.参数
发送邮件例子:
def sendmail():
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr#捕捉异常
try:
msg = MIMEText('邮件内容', 'plain', 'utf-8')
msg['From'] = formataddr(["张三",'zhangsan@163.com'])
msg['To'] = formataddr(["Python发送邮件",'lisi@163.com'])
msg['Subject'] = "Python发送邮件"
#开启smtp服务,并输入用户名、密码
server = smtplib.SMTP("smtp.163.com", 25)
server.login("zhangsan@163.com", "123456")
server.sendmail('zhangsan@163.com', ['lisi@163.com',], msg.as_string())
server.quit()
except:
#发送失败
return False
else:
#发送成功
return True
#return cc
ret = sendmail()
print(ret)
if ret == True: #也可以判断cc
print("邮件发送成功!")
else:
print("邮件发送失败!")
在函数中只要执行return,后续的代码都不会执行
def f1():
print(123)
return "111"
print(234)
r = f1()
print(r)
如果没有return会默认返回一个值None
def f2():
print(12345)
r2 = f2()
print(r2)
函数中的参数
1、普通参数(严格按照 顺序,将实际参数赋值给形式参数)
2、默认参数(必须放置在参数列表的最后)
3、指定参数(将实际参数赋值给指定的形式参数)
4、动态参数(*args、**kwargs)
5、万能参数(*args,**kwargs)
#形式参数:em
def sendmail(em):...while True:
#实际参数:email_addr
email_addr = input("请输入邮箱地址:")
result = sendmail(email_addr)
if result == True: # 也可以判断cc
print("邮件发送成功!")
else:
print("邮件发送失败!")
python规定:如果对某个参数默认值(mm = "OK"),必须将其放到末尾
def sendmail(email_addr, content, mm = "OK"):...while True:
#实际参数
email_addr = input("请输入邮箱地址:")
#指定参数:content ='haha'
result = sendmail(content ='haha', email_addr)
if result == True: # 也可以判断cc
print("邮件发送成功!")
else:
print("邮件发送失败!")
*参数,可以传递多个值,类型为tuple
把列表当成一个元素传递
def f1(*args):
print(args,type(args))
f1(11,22,33,'aa','ff')
如果传递参数时带*,则把列表中的每一个元素转化到元组中;其实就是在内部做了for循环将参数中的每一个值存放到元组中
def f1(*args):
print(args,type(args))
#f1(11,22,33,'aa','ff')
l1 = [11,22,33,'aa','ff']
f1(*l1)
传递**,则把传递的参数存放到字典中,所以需要指定key和value
def f1(**args):
print(args,type(args))
#f1(11,22,33,'aa','ff')
l1 = [11,22,33,'aa','ff']
f1(n1 = l1)
传递字典加*,需要指定key
def f1(**args):
print(args,type(args))
dic = {'k1':'v1','k2':'v2'}
f1(ni = dic)
传递字典加**
def f1(**args):
print(args,type(args))
dic = {'k1':'v1','k2':'v2'}
f1(**dic)
总结:加*默认将传入的参数放入元组中,加**默认将传入的参数放入字典中。
万能参数(*args, **kwargs)顺序固定
def f1(*args, **kwargs):
print(args,type(args))
print(kwargs, type(kwargs))
f1(11,22,33,44,'aa',k1='v1',k2='v2')
利用参数格式化输出
s = "I am {0} , age is {1}".format('wang',20)
s1 = "I am {0} , age is {1}".format(*['wang',20])
s3 = "I am {name} , age is {age}".format(name='wang',age=20)
dic = {'name':'wang','age':20}
s4 = "I am {name} , age is {age}".format(**dic)
创建两个相同函数,以后面创建的函数为准,前面创建的废弃
def f1(a1, a2):
return a1 + a2
def f1(a1, a2):
return a1 * a2
ret = f1(8, 8)
print(ret) #64
函数的参数在传递时是引用还是值?答案是引用。
def f2(a3):
a3.append(999)
li = [11,22,33,44]
f2(li)
print(li) #[11, 22, 33, 44, 999]
全局变量
1、所有的作用域里都可读;
2、优先使用自己定义的变量;
3、global name3进行重新赋值;
4、特殊:列表和字典,可修改不可重新赋值;
5、全局变量一定要全部大写。
NAME3 = "alex"
def f3():
global NAME3
NAME3 = "wang"
print(NAME3)
def f4():
print(NAME3)
f3()
f4()
NAME4 = [11,22,33,44,55]
def f5():
print(NAME4)
NAME4.append(66)
def f6():
print(NAME4)
f5()
f6()
函数实现登录注册
def login(username, password):
"""
用于用户登录
:param username:用户名
:param password:用户输入的密码
:return True:登录成功,False:登录失败
"""
f = open("db", "r")
for line in f:
line_list = line.strip().split("|")
if line_list[0] == username and line_list[1] == password:
return True
return False
def register(username, password):
"""
用户注册
:param username:用户名
:param password:密码
"""
# 追加模式
f = open("db", "a")
temp = "\n" + username + "|" + password
f.write(temp)
f.close()
def main():
t = input("1:登录: 2:注册")
if t == "1":
user = input("请输入用户名:")
pwd = input("请输入密码:")
r = login(user, pwd)
if r:
print("登录成功!")
else:
print("登录失败!")
elif t == "2":
user = input("请输入用户名:")
pwd = input("请输入密码:")
register(user, pwd)
main()
三元运算,三目运算
如果 1 == 1 成立,name = "wang";否则name = "radar"
name = "wang" if 1 == 1 else "radar"
简单的函数可以使用lambda表达式
def f1(a1):
return a1 + 100
ret1 = f1(10)
print(ret1)
#定义函数f2,冒号前面的为参数,冒号后面为表达式,隐含return功能,只能写一行,会返回结果
f2 = lambda a1, a2: a1 + 100 + a2
ret2 = f2(9,10)
print(ret2)
内置函数
1、取绝对值abs
n = abs(-1001)
print(n)
2、all,any
0,None,空字符串,空列表,空字典,空元组,bool值都是False
print(bool(0))
all中所有为真才为真
n = all([1,2,3,0])
print(n)
any中只要有真就为真
n = any([0,1,0,0,0])
print(n)
3、ascii()自动执行对象的__repr__方法
class Foo:
def __repr__(self):
return "65"
n = ascii(Foo())
print(n)
4、进制转换
#bin() 二进制
print(bin(23))
#oct() 八进制
print(oct(345))
#hex() 十六进制
print(hex(1111111))
5、字符串转字节bytes()
bytes(待转换的字符串, 按照什么编码)
汉字utf-8编码3个字节,GBK一个汉字两个字节,一个字节8位
#utf-8s = "二万画画"
# 01000110 01000110 01000110 01000110 01000110 01000110 01000110 01000110 01000110 01000110 01000110 01000110#十进制表示# 43 43 43 43 43 43 43 43 43 43 43 43
m = bytes(s, encoding="utf-8")
m1 = bytes(s, encoding="GBK")
print(m)
print(m1)
6、字符串转换为字节列表bytearray()
m2 = bytearray(s, encoding="utf-8")
print(m2)#字节转换为字符串,编码方式保持一致
m3 = str(m2,encoding="utf-8")
print(m3)
7、文件操作open
#打开文件
f = open('db','r') #只读
f = open('db','w') #只写,写之前清空文件
f = open('db','x') #文件存在就报错;不存在创建并只写
f = open('db','a') #追加
#操作文件
f.read()
f.readlines()
f.readline()
#关闭文件
f.close()
r+:即可读又可写,需要找到指针的位置
f = open('db', 'r+', encoding="utf-8")
如果打开模式没有b,则read按照字符读取
data = f.read(3)
tell当前指针所在的位置(字节)
print(f.tell())
调整写入指针位置(字节)
f.seek(f.tell())
当前指针位置开始覆盖写入
f.write("admin")
f.close()
打开文件的模式有:
r ,只读模式【默认】
w,只写模式【不可读;不存在则创建;存在则清空内容;】
x, 只写模式【不可读;不存在则创建,存在则报错】
a, 追加模式【可读; 不存在则创建;存在则只追加内容;】
"+" 表示可以同时读写某个文件
r+, 读写【可读,可写】
w+,写读【可读,可写】
x+ ,写读【可读,可写】
a+, 写读【可读,可写】
"b"表示以字节的方式操作
rb 或 r+b
wb 或 w+b
xb 或 w+b
ab 或 a+b
注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型
fileno文件描述符
flush刷新
readline仅读取一行
truncate截断,指针位置后面的内容清空
f = open('db','r+',encoding = 'utf-8')
for line in f:
print(line)
关闭文件
f.close
with open('xb') as f:
pass
with
with open('db') as f:
pass
#读取db1前10行,然后以只写方式写入db2
with open('db1', 'r', encoding='utf-8') as f1, open("db2", 'w', encoding='utf-8') as f2:
times = 0
for line in f1:
times += 1
if times <= 10:
f2.write(line)
else:
break
#取一行写一行
with open('db3', 'r', encoding='utf-8') as f3, open("db4", 'w', encoding='utf-8') as f4:
for line2 in f3:
new_str = line2.replace("alex", 'steven')
f2.write(new_str)