题目汇总
【文件与文件系统】练习题
1、打开中文字符的文档时,会出现乱码,Python自带的打开文件是否可以指定文字编码?还是只能用相关函数?
2、编写程序查找最长的单词
输入文档: res/test.txt
题目说明:
"""
Input file
test.txt
Output file
['general-purpose,', 'object-oriented,']
"""
def longest_word(filename):
# your code here
pass
【类与对象】
1、以下类定义中哪些是类属性,哪些是实例属性?
2、怎么定义私有方法?
3、尝试执行以下代码,并解释错误原因:
class C:
def myFun():
print('Hello!')
c = C()
c.myFun()
4、按照以下要求定义一个游乐园门票的类,并尝试计算2个成人+1个小孩平日票价。
要求:
平日票价100元
周末票价为平日的120%
儿童票半价
class Ticket():
# your code here
【字典】
data = {
'python': {'上学期': '90', '下学期': '95'},
'c++': ['95', '96', '97'],
'java': [{'月考':'90', '期中考试': '94', '期末考试': '98'}]
}
各门课程的考试成绩存储方式并不相同,有的用字典,有的用列表,
但是分数都是字符串类型,请实现函数transfer_score(score_dict),将分数修改成int类型
def transfer_score(data):
# your code here
【集合】练习题:
1、怎么表示只包含一个数字1的元组。
(1,)
2、求两个集合{6, 7, 8},{7, 8, 9}中不重复的元素(差集指的是两个集合交集外的部分)???
答案:({6, 7, 8}|{7, 8, 9})-({6, 7, 8}&{7, 8, 9})
3、求{'A', 'B', 'C'}中元素在 {'B', 'C', 'D'}中出现的次数。
a1 = {'A', 'B', 'C'}
a2 = {'B', 'C', 'D'}
for i in a1:
if i in a2:
print('%s在%s中出现1次'%(i,a2))
else:
print('%s在%s中出现0次'%(i,a2))
【序列】
sort() 和 sorted() 区别:sort()作用于原始,而 sorted() 使用后,原始不变。
求列表 [2,3,4,5] 中每个元素的立方根:[i**3 for i in [2,3,4,5] ]
【函数】
1、闭包中,怎么对数字、字符串、元组等不可变元素更新。
2、分别根据每一行的首元素和尾元素大小对二维列表 a = [[6, 5], [3, 7], [2, 8]] 排序。(利用lambda表达式)
sorted(a,key=lambda x:x[0])
sorted(a,key=lambda x:x[1])
3、利用python解决汉诺塔问题?
有a、b、c三根柱子,在a柱子上从下往上按照大小顺序摞着64片圆盘,把圆盘从下面开始按大小顺序重新摆放在c柱子上,尝试用函数来模拟解决的过程。(提示:将问题简化为已经成功地将a柱上面的63个盘子移到了b柱)
【模块】
1、怎么查出通过 from xx import xx导⼊的可以直接调用的方法?
2、了解Collection模块,编写程序以查询给定列表中最常见的元素。
题目说明:
输入:language = ['PHP', 'PHP', 'Python', 'PHP', 'Python', 'JS', 'Python', 'Python','PHP', 'Python']
输出:Python
"""
Input file
language = ['PHP', 'PHP', 'Python', 'PHP', 'Python', 'JS', 'Python', 'Python','PHP', 'Python']
Output file
Python
"""
def most_element(language):
""" Return a list of lines after inserting a word in a specific line. """
# your code here
day9:文件与文件系统【08月08日 23:59】
【打开文件】open(file, mode='r', buffering=None, encoding=None, errors=None,
newline=None, closefd=True)
Open file and return a stream. Raise OSError upon failure.
file: 必需,文件路径(相对或者绝对路径)。
mode: 可选,文件打开模式
buffering: 设置缓冲
encoding: 一般使用utf8
errors: 报错级别
newline: 区分换行符
【常见的mode如下表所示】打开模式 执行操作
'r' 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
'w' 打开一个文件只用于写入。
如果该文件已存在,则打开文件,并从开头开始编辑。即原有内容会被删除。
如果该文件不存在,创建新文件。
'x' 写模式,新建一个文件,如果该文件已存在则会报错。
'a' 追加模式,打开一个文件用于追加。
如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。
如果该文件不存在,创建新文件进行写入。
'b' 以二进制模式打开文件。一般用于非文本文件,如:图片。
't' 以文本模式打开(默认)。一般用于文本文件,如:txt。
'+' 可读写模式(可添加到其它模式中使用)
【文件对象方法】fileObject.readlines()用于读取所有行(直到结束符 EOF)并返回列表,该列表可以由 Python 的 for... in ... 结构进行处理。
【例】
f = open('将进酒.txt', 'r')
lines = f.readlines()
print(lines)
for each in lines:
each.strip()
print(each)
# 君不见,黄河之水天上来,奔流到海不复回。
# 君不见,高堂明镜悲白发,朝如青丝暮成雪。
# 人生得意须尽欢,莫使金樽空对月。
# 天生我材必有用,千金散尽还复来。
# 烹羊宰牛且为乐,会须一饮三百杯。
# 岑夫子,丹丘生,将进酒,杯莫停。
# 与君歌一曲,请君为我倾耳听。
# 钟鼓馔玉不足贵,但愿长醉不复醒。
# 古来圣贤皆寂寞,惟有饮者留其名。
# 陈王昔时宴平乐,斗酒十千恣欢谑。
# 主人何为言少钱,径须沽取对君酌。
# 五花马,千金裘,呼儿将出换美酒,与尔同销万古愁。
f.close()
如果文件打开模式带b,那写入文件内容时,str(参数)要用encode方法转为bytes形式,否则报错:TypeError: a bytes-like object is required, not 'str'。
【例】
str = '...'
# 文本 = Unicode字符序列
# 相当于 string 类型
str = b'...'
# 文本 = 八位序列(0到255之间的整数)
# 字节文字总是以‘b’或‘B’作为前缀;它们产生一个字节类型的实例,而不是str类型。
# 相当于 byte[]
fileObject.writelines(sequence)向文件写入一个序列字符串列表,如果需要换行则要自己加入每行的换行符\n。
【例】
f = open('test.txt', 'w+')
seq = ['小马的程序人生\n', '老马的程序人生']
f.writelines(seq)
f.seek(0, 0)
for each in f:
print(each)
# 小马的程序人生
# 老马的程序人生
f.close()
【简洁的 with 语句】一些对象定义了标准的清理行为,无论系统是否成功的使用了它,一旦不需要它了,那么这个标准的清理行为就会执行。
关键词 with 语句就可以保证诸如文件之类的对象在使用完之后一定会正确的执行它的清理方法。
【例】
try:
f = open('myfile.txt', 'w')
for line in f:
print(line)
except OSError as error:
print('出错啦!%s' % str(error))
finally:
f.close()
# 出错啦!not readable
这段代码执行完毕后,就算在处理过程中出问题了,文件 f 总是会关闭。
【例】
try:
with open('myfile.txt', 'w') as f:
for line in f:
print(line)
except OSError as error:
print('出错啦!%s' % str(error))
# 出错啦!not readable
【序列化与反序列化】
Python 的 pickle 模块实现了基本的数据序列和反序列化。
通过 pickle 模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储。
通过 pickle 模块的反序列化操作,我们能够从文件中创建上一次程序保存的对象。
pickle模块中最常用的函数为:
pickle.dump(obj, file, [,protocol]) 将obj对象序列化存入已经打开的file中。
obj:想要序列化的obj对象。
file:文件名称。
protocol:序列化使用的协议。如果该项省略,则默认为0。如果为负值或HIGHEST_PROTOCOL,则使用最高的协议版本。
pickle.load(file) 将file中的对象序列化读出。
file:文件名称。
【例】
import pickle
dataList = [[1, 1, 'yes'],
[1, 1, 'yes'],
[1, 0, 'no'],
[0, 1, 'no'],
[0, 1, 'no']]
dataDic = {0: [1, 2, 3, 4],
1: ('a', 'b'),
2: {'c': 'yes', 'd': 'no'}}
# 使用dump()将数据序列化到文件中
fw = open(r'.\dataFile.pkl', 'wb')
# Pickle the list using the highest protocol available.
pickle.dump(dataList, fw, -1)
# Pickle dictionary using protocol 0.
pickle.dump(dataDic, fw)
fw.close()
# 使用load()将数据从文件中序列化读出
fr = open('dataFile.pkl', 'rb')
data1 = pickle.load(fr)
print(data1)
data2 = pickle.load(fr)
print(data2)
fr.close()
# [[1, 1, 'yes'], [1, 1, 'yes'], [1, 0, 'no'], [0, 1, 'no'], [0, 1, 'no']]
# {0: [1, 2, 3, 4], 1: ('a', 'b'), 2: {'c': 'yes', 'd': 'no'}}
day8:模块与datetime模块【08月07日 23:59】
【脚本语言(动态的逐行解释运行,如python) VS 编译型语言(先将程序编译成二进制再运行)】对于很多编程语言来说,程序都必须要有一个入口,而 Python 则不同,它属于脚本语言,不像编译型语言那样先将程序编译成二进制再运行,而是动态的逐行解释运行。也就是从脚本第一行开始运行,没有统一的入口。
【模块】是一个包含所有你定义的函数和变量的文件,其后缀名是.py。模块可以被别的程序引入,以使用该模块中的函数等功能。这也是使用 Python 标准库的方法。
【容器、函数、类、模块】
容器 -> 数据的封装
函数 -> 语句的封装
类 -> 方法和属性的封装
模块 -> 程序文件
【命名空间因为对象的不同,也有所区别】可以分为如下几种:
- 内置命名空间(Built-in Namespaces):Python 运行起来,它们就存在了。内置函数的命名空间都属于内置命名空间,所以,我们可以在任何程序中直接运行它们,比如
id()
,不需要做什么操作,拿过来就直接使用了。 - 全局命名空间(Module:Global Namespaces):每个模块创建它自己所拥有的全局命名空间,不同模块的全局命名空间彼此独立,不同模块中相同名称的命名空间,也会因为模块的不同而不相互干扰。
-
本地命名空间(Function & Class:Local Namespaces):模块中有函数或者类,每个函数或者类所定义的命名空间就是本地命名空间。如果函数返回了结果或者抛出异常,则本地命名空间也结束了。
上述三种命名空间的关系:程序在查询上述三种命名空间的时候,就按照从里到外的顺序,即:Local Namespaces --> Global Namesspaces --> Built-in Namesspaces。
【导入模块】
- 第一种:import 模块名
- 第二种:from 模块名 import 函数名
- 第三种:import 模块名 as 新名字
【if __name__ == '__main__'】
由此我们可知:如果一个 .py 文件(模块)被直接运行时,其__name__值为__main__,即模块名为__main__。
所以,if __name__ == '__main__'的意思是:
当 .py 文件被直接运行时,if __name__ == '__main__'之下的代码块将被运行;
当 .py 文件以模块形式被导入时,if __name__ == '__main__'之下的代码块不被运行。
【datetime】是 Python 中处理日期的标准模块,它提供了 4 种对日期和时间进行处理的类:datetime、date、time 和 timedelta。
- datetime.now(tz=None) 获取当前的日期时间,输出顺序为:年、月、日、时、分、秒、微秒。
- datetime.timestamp() 获取以 1970年1月1日为起点记录的秒数。
- datetime.fromtimestamp(tz=None) 使用 unixtimestamp 创建一个 datetime。
- datetime.strftime(fmt) 格式化 datetime 对象。
【例子】如何创建一个 datetime 对象?
import datetime
dt = datetime.datetime(year=2020, month=6, day=25, hour=11, minute=23, second=59)
print(dt) # 2020-06-25 11:23:59
print(dt.timestamp()) # 1593055439.0
dt = datetime.datetime.fromtimestamp(1593055439.0)
print(dt) # 2020-06-25 11:23:59
print(type(dt)) # <class 'datetime.datetime'>
dt = datetime.datetime.now()
print(dt) # 2020-06-25 11:11:03.877853
print(type(dt)) # <class 'datetime.datetime'>
【例子】如何将 datetime 对象转换为任何格式的日期?
import datetime
dt = datetime.datetime(year=2020, month=6, day=25, hour=11, minute=51, second=49)
s = dt.strftime("'%Y/%m/%d %H:%M:%S")
print(s) # '2020/06/25 11:51:49
s = dt.strftime('%d %B, %Y, %A')
print(s) # 25 June, 2020, Thursday
day7:类与对象【08月05日 23:59】
【对象(类的实例) = 属性 + 方法】类主要定义对象的结构,然后我们以类为模板创建对象。类不但包含方法定义,而且还包含所有实例共享的数据。
- 封装:信息隐蔽技术;
- 继承:子类自动共享父类之间数据和方法的机制;
- 多态:不同对象对同一方法响应不同的行动。
【Python 的 self 相当于 C++ 的 this 指针】类的方法与普通的函数只有一个特别的区别 —— 它们必须有一个额外的第一个参数名称(对应于该实例,即该对象本身),按照惯例它的名称是 self。在调用方法时,我们无需明确提供与参数 self 相对应的参数。
class Ball:
def setName(self, name):
self.name = name
def kick(self):
print("我叫%s,该死的,谁踢我..." % self.name)
a = Ball()
a.setName("球A")
b = Ball()
b.setName("球B")
c = Ball()
c.setName("球C")
a.kick()
# 我叫球A,该死的,谁踢我...
b.kick()
# 我叫球B,该死的,谁踢我...
【Python 的魔法方法】
类有一个名为 __init__ (self[, param1, param2...])
的魔法方法,该方法在类实例化时会自动调用。
class Ball:
def __init__(self, name):
self.name = name
def kick(self):
print("我叫%s,该死的,谁踢我..." % self.name)
a = Ball("球A")
b = Ball("球B")
c = Ball("球C")
a.kick()
# 我叫球A,该死的,谁踢我...
b.kick()
# 我叫球B,该死的,谁踢我...
【公有和私有】定义私有变量只需要在变量名或函数名前加上“__”两个下划线,那么这个函数或变量就会为私有的了。
【继承】
【组合】
【类属性和实例属性区别】
- 类属性:类外面,可以通过实例对象.类属性和类名.类属性进行调用。类里面,通过self.类属性和类名.类属性进行调用。
- 实例属性 :类外面,可以通过实例对象.实例属性调用。类里面,通过self.实例属性调用。
- 实例属性就相当于局部变量。出了这个类或者这个类的实例对象,就没有作用了。
- 类属性就相当于类里面的全局变量,可以和这个类的所有实例对象共享。
day6:函数与Lambda表达式【08月02日 23:59】
【Python 里有两类函数】
第一类:用 def 关键词定义的正规函数
第二类:用 lambda 关键词定义的匿名函数
函数
【Python 把函数也当成对象(Python 里“万物皆对象”)】可以从另一个函数中返回出来而去构建高阶函数,比如:1参数是函数;2返回值是函数。
【函数的调用】
def printme(str):
print(str)
printme("我要调用用户自定义函数!") # 我要调用用户自定义函数!
printme("再次调用同一函数") # 再次调用同一函数
temp = printme('hello') # hello
print(temp) # None
【函数参数(可元组、关字典:可变参数是元组、关键字参数是字典)】def def functionname(arg1, arg2=v, *args, *, nkw, **kw):
- 位置参数 (positional argument);
- 默认参数 (default argument):默认参数一定要放在位置参数 后面;
- 可变参数 (variable argument): *args - 可变参数,可以是从零个到任意个,自动组装成【元组(可变参数是元组)】;
- 关键字参数 (keyword argument): **kw - 关键字参数,可以是从零个到任意个,自动组装成【字典(关键字参数是字典)】;
- 命名关键字参数 (name keyword argument): *, nkw - 命名关键字参数,用户想要输入的关键字参数,定义方式是在nkw 前面加个分隔符 * ,否则定义的是位置参数;
- 参数组合的顺序:位置参数、默认参数、可变参数和关键字参数;位置参数、默认参数、命名关键字参数和关键字参数;
【可变参数是元组、关键字参数是字典】
- 可变参数允许传入零个到任意个参数,它们在函数调用时自动组装为一个元组 (tuple)。
- 关键字参数允许传入零个到任意个参数,它们在函数内部自动组装为一个字典 (dict)。
def printinfo(arg1, *args, **kwargs):
print(arg1)
print(args)
print(kwargs)
printinfo(70, 60, 50)
# 70
# (60, 50)
# {}
printinfo(70, 60, 50, a=1, b=2)
# 70
# (60, 50)
# {'a': 1, 'b': 2}
【命名关键字参数】
def printinfo(arg1, *, nkw, **kwargs):
print(arg1)
print(nkw)
print(kwargs)
printinfo(70, nkw=10, a=1, b=2)
# 70
# 10
# {'a': 1, 'b': 2}
printinfo(70, 10, a=1, b=2)
# TypeError: printinfo() takes 1 positional argument but 2 were given
没有写参数名nwk,因此 10 被当成「位置参数」,而原函数只有 1 个位置函数,现在调用了 2 个,因此程序会报错。
【函数的返回值】
def add(a, b):
return a + b
print(add(1, 2)) # 3
print(add([1, 2, 3], [4, 5, 6])) # [1, 2, 3, 4, 5, 6]
add((1,2,3),(2,3)) #(1, 2, 3, 2, 3)
add({1,2,3},{2,3}) #报错:unsupported operand type(s) for +: 'set' and 'set'
【闭包】
- 是函数式编程的一个重要的语法结构,是一种特殊的内嵌函数。
- 如果在一个内部函数里对外层非全局作用域的变量进行引用,那么内部函数就被认为是闭包。
- 通过闭包可以访问外层非全局作用域的变量,这个作用域称为 闭包作用域。
【例子】
def funX(x):
def funY(y):
return x * y
return funY
i = funX(8)
print(type(i)) # <class 'function'>
print(i(5)) # 40
【例子:闭包的返回值通常是函数】
def make_counter(init):
counter = [init]
def inc(): counter[0] += 1
def dec(): counter[0] -= 1
def get(): return counter[0]
def reset(): counter[0] = init
return inc, dec, get, reset
inc, dec, get, reset = make_counter(0)
inc()
inc()
inc()
print(get()) # 3
dec()
print(get()) # 2
reset()
print(get()) # 0
【例子:如果要修改闭包作用域中的变量则需要 nonlocal 关键字】
def outer():
num = 10
def inner():
nonlocal num # nonlocal关键字声明
num = 100
print(num)
inner()
print(num)
outer()
# 100
# 100
Lambda 表达式
【lambda argument_list: expression】
argument_list - 函数参数,它们可以是位置参数、默认参数、关键字参数,和正规函数里的参数类型一样。
sumary = lambda arg1, arg2: arg1 + arg2
print(sumary(10, 20)) # 30
func = lambda *args: sum(args)
print(func(1, 2, 3, 4, 5)) # 15
【函数式编程】 是指代码中每一块都是不可变的,都由纯函数的形式组成。这里的纯函数,是指函数本身相互独立、互不影响,对于相同的输入,总会有相同的输出,没有任何副作用。
【匿名函数 常常应用于函数式编程的高阶函数 (high-order function)中】主要有两种形式:
- 参数是函数 (filter, map)
- 返回值是函数 (closure)
【filter(function, iterable) 过滤序列】
过滤掉不符合条件的元素,返回一个迭代器对象;
如果要转换为列表,可以使用 list() 来转换。
odd = lambda x: x % 2 == 1
templist = filter(odd, [1, 2, 3, 4, 5, 6, 7, 8, 9])
print(list(templist)) # [1, 3, 5, 7, 9]
【map(function, *iterables) 】
根据提供的函数对指定序列做映射。
m2 = map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
print(list(m2))
# [3, 7, 11, 15, 19]
【自己定义高阶函数】
def apply_to_list(fun, some_list):
return fun(some_list)
lst = [1, 2, 3, 4, 5]
print(apply_to_list(sum, lst))
# 15
print(apply_to_list(len, lst))
# 5
print(apply_to_list(lambda x: sum(x) / len(x), lst))
# 3.0
day5:字典、集合和序列【07月31日 23:59】
1字典
【序列(字符串、元组、列表属于序列类型,而字典是 Python 唯一的一个 映射类型)】是以连续的整数为索引,与此不同的是,【字典以"关键字"为索引】,关键字可以是任意不可变类型(通常用字符串或数值)。
【如何快速判断一个数据类型 X 是不是可变类型的呢?(可被哈希,即不可变,如整数、字符和元组;反过来,不可被哈希,即可变,如列表、集合、字典)】两种方法:
麻烦方法:用 id(X) 函数,对 X 进行某种操作,比较操作前后的 id,如果不一样,则 X 不可变,如果一样,则 X 可变。
便捷方法:用 hash(X),只要不报错,证明 X 可被哈希,即不可变,反过来不可被哈希,即可变。
print(hash('Name')) # -9215951442099718823
print(hash((1, 2, 'Python'))) # 823362308207799471
print(hash([1, 2, 'Python']))
# TypeError: unhashable type: 'list'
print(hash({1, 2, 3}))
# TypeError: unhashable type: 'set'
【字典(空间取代时间,即大空间、短时间——查找、插入快,但占内存)】dict 查找和插入的速度极快,不会随着 key 的增加而增加,但是需要占用大量的内存。
- dict(mapping) new dictionary initialized from a mapping object's (key, value) pairs
dic1 = dict([('apple', 4139), ('peach', 4127), ('cherry', 4098)])
print(dic1) # {'cherry': 4098, 'apple': 4139, 'peach': 4127}
dic2 = dict((('apple', 4139), ('peach', 4127), ('cherry', 4098)))
print(dic2) # {'peach': 4127, 'cherry': 4098, 'apple': 4139}
- dict(**kwargs) -> new dictionary initialized with the name=value pairs in the keyword argument list. For example: dict(one=1, two=2)【例子】这种情况下,键只能为字符串类型,并且创建的时候字符串不能加引号,加上就会直接报语法错误。
dic = dict(name='Tom', age=10) #name不能加引号
print(dic) # {'name': 'Tom', 'age': 10}
print(type(dic)) # <class 'dict'>
【字典的内置方法】
- dict.fromkeys(seq[, value]) 用于创建一个新字典,以序列 seq 中元素做字典的键,value 为字典所有键对应的初始值。
seq = ('name', 'age', 'sex')
dic1 = dict.fromkeys(seq)
print(dic1)
# {'name': None, 'age': None, 'sex': None}
dic2 = dict.fromkeys(seq, 10)
print(dic2)
# {'name': 10, 'age': 10, 'sex': 10}
dic3 = dict.fromkeys(seq, ('小马', '8', '男')) ##重视:此处并非一一对应关系
print(dic3)
# {'name': ('小马', '8', '男'), 'age': ('小马', '8', '男'), 'sex': ('小马', '8', '男')}
- dict.keys()返回一个可迭代对象,可以使用 list() 来转换为列表,列表为字典中的所有键。
dic = {'Name': 'lsgogroup', 'Age': 7}
print(dic.keys()) # dict_keys(['Name', 'Age'])
lst = list(dic.keys()) # 转换为列表
print(lst) # ['Name', 'Age']
- dict.setdefault(key, default=None)和get()方法 类似, 如果键不存在于字典中,将会添加键并将值设为默认值,详见下面例子。
dic = {'Name': 'Lsgogroup', 'Age': 7}
print("Age 键的值为 : %s" % dic.setdefault('Age', None)) # Age 键的值为 : 7
print("Sex 键的值为 : %s" % dic.setdefault('Sex', None)) # Sex 键的值为 : None
print(dic)
# {'Age': 7, 'Name': 'Lsgogroup', 'Sex': None}
注意区别:dict.get(key, default=None) 返回指定键的值,如果值不在字典中返回默认值。
dic = {'Name': 'Lsgogroup', 'Age': 27}
print("Age 值为 : %s" % dic.get('Age')) # Age 值为 : 27
print("Sex 值为 : %s" % dic.get('Sex', "NA")) # Sex 值为 : NA
print(dic) # {'Name': 'Lsgogroup', 'Age': 27}
- key in dict in 操作符用于判断【键(而非值?)】是否存在于字典中,如果键在字典 dict 里返回true,否则返回false。
- dict.pop(key[,default])删除字典给定键 key 所对应的值,返回值为被删除的值。key 值必须给出。若key不存在,则返回 default 值。
- del dict[key] 删除字典给定键 key 所对应的值。
dic1 = {1: "a", 2: [1, 2]}
print(dic1.pop(1), dic1) # a {2: [1, 2]}
# 设置默认值,必须添加,否则报错
print(dic1.pop(3, "nokey"), dic1) # nokey {2: [1, 2]}
del dic1[2]
print(dic1) # {}
- 深拷贝(直接赋值)与浅拷贝(copy) 的区别
dic1 = {'user': 'lsgogroup', 'num': [1, 2, 3]}
# 引用对象
dic2 = dic1
# 浅拷贝父对象(一级目录),子对象(二级目录)不拷贝,还是引用
dic3 = dic1.copy()
print(id(dic1)) # 148635574728
print(id(dic2)) # 148635574728
print(id(dic3)) # 148635574344
# 修改 data 数据
dic1['user'] = 'root'
dic1['num'].remove(1)
# 输出结果
print(dic1) # {'user': 'root', 'num': [2, 3]}
print(dic2) # {'user': 'root', 'num': [2, 3]}
print(dic3) # {'user': 'runoob', 'num': [2, 3]} ##此处为啥 'num': [2, 3]
- dict.update(dict2)把字典参数 dict2 的 key:value对 更新到字典 dict 里。
dic = {'Name': 'Lsgogroup', 'Age': 7}
dic2 = {'Sex': 'female', 'Age': 8}
dic.update(dic2)
print(dic)
# {'Sex': 'female', 'Age': 8, 'Name': 'Lsgogroup'}
2集合
【集合: set 是无序和无重复元素的集合】无序 (unordered,不可以为集合创建索引或执行切片(slice)操作,也没有键(keys)可用来获取集合中元素的值,但是可以通过in或not in判断一个元素是否在集合中已经存在) 和唯一 (unique)。
- set1 & set2 返回两个集合的交集。
- set1 | set2 返回两个集合的并集,或者set.union(set1, set2) 返回两个集合的并集。
- set1 - set2 返回集合的差集(补集?)。
- set1 ^ set2 返回集合的异或(并集 - 交集)。
- set1 <= set2 判断集合是不是被其他集合包含,如果是则返回 True,否则返回 False。
【集合的创建】在创建空集合的时候只能使用s = set(),因为s = {}创建的是空字典。
basket = set() #先创建对象再加入元素。
basket.add('apple')
basket.add('banana')
print(basket) # {'banana', 'apple'}
【set(value)工厂函数,把字符串、列表、元组转换成集合】
a = set('abracadabra')
print(a)
# {'r', 'b', 'd', 'c', 'a'}
b = set(("Google", "Lsgogroup", "Taobao", "Taobao"))
print(b)
# {'Taobao', 'Lsgogroup', 'Google'}
c = set(["Google", "Lsgogroup", "Taobao", "Google"])
print(c)
# {'Taobao', 'Lsgogroup', 'Google'}
【集合的内置方法】
- set.add(elmnt):用add给集合添加元素,如果添加的元素在集合中已存在,则不执行任何操作。
- set.remove(item) 用于移除集合中的指定元素。如果元素不存在,则会发生错误(但 discard() 方法不会)。
3序列
【序列类型:字符串、列表、元组、集合和字典】这些序列支持一些通用的操作,但比较特殊的是,集合和字典不支持【1索引、2切片、3相加、4相乘】这四个操作。
【可迭代对象的转换:list()有区别】
- str(obj) 把obj对象转换为字符串
a = 123
a = str(a)
print(a) # 123
- list(sub) 把一个可迭代对象转换为列表。
a = list()
print(a) # []
b = 'I Love LsgoGroup' ##高度注意,我的错点
b = list(b)
print(b)
# ['I', ' ', 'L', 'o', 'v', 'e', ' ', 'L', 's', 'g', 'o', 'G', 'r', 'o', 'u', 'p']
c = (1, 1, 2, 3, 5, 8)
c = list(c)
print(c) # [1, 1, 2, 3, 5, 8]
- tuple(sub) 把一个可迭代对象转换为元组。
【内置函数】
- sorted(iterable, key=None, reverse=False) 对所有可迭代的对象进行排序操作。
iterable -- 可迭代对象。
key -- 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。
x = [-8, 99, 3, 7, 83]
print(sorted(x)) # [-8, 3, 7, 83, 99]
print(sorted(x, reverse=True)) # [99, 83, 7, 3, -8]
t = ({"age": 20, "name": "a"}, {"age": 25, "name": "b"}, {"age": 10, "name": "c"})
x = sorted(t, key=lambda a: a["age"])
print(x)
# [{'age': 10, 'name': 'c'}, {'age': 20, 'name': 'a'}, {'age': 25, 'name': 'b'}]
- reversed(seq) 函数返回一个反转的迭代器。
seq -- 要转换的序列,可以是 tuple, string, list 或 range。
s = 'lsgogroup'
x = reversed(s)
print(type(x)) # <class 'reversed'>
print(x) # <reversed object at 0x000002507E8EC2C8>
print(list(x))
# ['p', 'u', 'o', 'r', 'g', 'o', 'g', 's', 'l']
t = ('l', 's', 'g', 'o', 'g', 'r', 'o', 'u', 'p')
print(list(reversed(t)))
# ['p', 'u', 'o', 'r', 'g', 'o', 'g', 's', 'l']
r = range(5, 9)
print(list(reversed(r)))
# [8, 7, 6, 5]
x = [-8, 99, 3, 7, 83]
print(list(reversed(x)))
# [83, 7, 3, 99, -8]
- zip(iter1 [,iter2 [...]])
用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象,这样做的好处是节约了不少的内存。
我们可以使用 list() 转换来输出列表。
如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。
a = [1, 2, 3]
b = [4, 5, 6]
c = [4, 5, 6, 7, 8]
zipped = zip(a, b)
print(zipped) # <zip object at 0x000000C5D89EDD88>
print(list(zipped)) # [(1, 4), (2, 5), (3, 6)]
zipped = zip(a, c)
print(list(zipped)) # [(1, 4), (2, 5), (3, 6)]
a1, a2 = zip(*zip(a, b))
print(list(a1)) # [1, 2, 3]
print(list(a2)) # [4, 5, 6]
day4:列表、元组和字符串【07月28日 23:59】
列表
【容器数据类型】
列表<class 'list'>
元组<class 'tuple'>
字典<class 'dict'>
集合<class 'set'>
字符串<class 'str'>
【利用推导式创建列表】
[0] * 5
# [0, 0, 0, 0, 0] <class 'list'>
[[0] * 3 for row in range(4)]
# [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] <class 'list'>
[[0 for col in range(3)] for row in range(4)]
# [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] <class 'list'>
【由于list的元素可以是任何对象,因此列表中所保存的是对象的指针】即使保存一个简单的[1,2,3],也有3个指针和3个整数对象。
x = [a] * 4操作中,只是创建4个指向list的引用,所以一旦a改变,x中4个a也会随之改变。
【例子】
x = [[0] * 3] * 4
print(x, type(x))
# [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] <class 'list'>
x[0][0] = 1
print(x, type(x))
# [[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0]] <class 'list'>
【创建一个混合列表】
【例子】
mix = [1, 'lsgo', 3.14, [1, 2, 3]]
print(mix, type(mix))
# [1, 'lsgo', 3.14, [1, 2, 3]] <class 'list'>
【列表不像元组,列表内容可更改 (mutable)】因此附加 (append, extend)、插入 (insert)、删除 (remove, pop) 这些操作都可以用在它身上。
append 是追加,把一个东西整体添加在列表后;而 extend 是扩展,把一个东西里的所有元素添加在列表后。
list.extend(seq) 在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
【例子】
x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
x.extend(['Thursday', 'Sunday'])
print(x)
# ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Thursday', 'Sunday']
print(len(x)) # 7
【删除列表中的元素】list.remove(obj) 移除列表中某个值(指定具体要删除的元素)的第一个匹配项;list.pop([index=-1]) 移除列表中的一个元素(指定一个索引,默认最后一个元素),并且返回该元素的值;del var1[, var2 ……] 删除单个或多个对象。
如果你要从列表中删除一个元素,且不再以任何方式使用它,就使用del语句;如果你要在删除元素后还能继续使用它,就使用方法pop()。
【例子】如果知道要删除的元素在列表中的位置,可使用del语句。
x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
print(x[0:2]) #['Monday', 'Tuesday']
del x[0:2]
print(x) # ['Wednesday', 'Thursday', 'Friday']
【浅拷贝与深拷贝】复制列表中的所有元素(浅拷贝week[:])
week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
print(week[:])
# ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
【列表的常用操作符】
等号操作符==(「等号 ==」,只有成员、成员位置都相同时才返回True);
连接操作符 +(首尾拼接,类似 extend());
重复操作符 *(复制拼接);
成员关系操作符 in、not in。
前面三种方法(append, extend, insert)可对列表增加元素,它们没有返回值,是直接修改了原数据对象。 而将两个list相加,需要创建新的 list 对象,从而需要消耗额外的内存,特别是当 list 较大时,尽量不要使用 “+” 来添加list。
【list.count(obj) 】统计某个元素在列表中出现的次数。
【list.sort(key=None, reverse=False)】对原列表进行排序。
# 获取列表的第二个元素
def takeSecond(elem):
return elem[1]
x = [(2, 2), (3, 4), (4, 1), (1, 3)]
x.sort(key=takeSecond)
print(x)
# [(4, 1), (2, 2), (1, 3), (3, 4)]
x.sort(key=lambda a: a[0])
print(x)
# [(1, 3), (2, 2), (3, 4), (4, 1)]
元组
【索引 (indexing) 和切片 (slicing)】元组与列表类似,也用整数来对它进行索引 (indexing) 和切片 (slicing)。
【创建元组】创建元组可以用小括号 (),也可以什么都不用,为了可读性,建议还是用 ()。
元组中只包含一个元素时,需要在元素后面添加逗号,否则括号会被当作运算符使用。
【例子】
print(8 * (8)) # 64
print(8 * (8,)) # (8, 8, 8, 8, 8, 8, 8, 8)
【更新和删除一个元组】元组有不可更改 (immutable) 的性质,因此不能直接给元组的元素赋值,但是只要元组中的元素可更改 (mutable),那么我们可以直接更改其元素,注意这跟赋值其元素不同。
【内置方法】元组大小和内容都不可更改,因此只有 count 和 index 两种方法。
【解压元组】如果你只想要元组其中几个元素,用通配符「*」,英文叫 wildcard,在计算机语言中代表一个或多个元素。下例就是把多个元素丢给了 rest 变量。
t = 1, 2, 3, 4, 5
a, b, *rest, c = t
print(a, b, c) # 1 2 5
print(rest) # [3, 4]
【例子】如果你根本不在乎 rest 变量,那么就用通配符「*」加上下划线「_」。
t = 1, 2, 3, 4, 5
a, b, *_ = t
print(a, b) # 1 2
【拆包过程是什么?】
a, b = 1, 2
上述过程属于拆包吗?
可迭代对象拆包时,怎么赋值给占位符?
字符串
【Python 的常用转义字符】\n 换行;\r 回车。
【例子】原始字符串只需要在字符串前边加一个英文字母 r 即可。
print(r'C:\Program Files\Intel\Wifi\Help')
# C:\Program Files\Intel\Wifi\Help
【字符串的常用内置方法】swapcase() 将字符串中大写转换为小写,小写转换为大写。
'xiaoxie'.capitalize() #'Xiaoxie'
'Xiaoxie'.upper() #'XIAOXIE'
'Xiaoxie'.swapcase() #'xIAOXIE'
count(str, beg= 0,end=len(string)) 返回str在 string 里面出现的次数,如果beg或者end指定则返回指定范围内str出现的次数。
【例子】
str2 = "DAXIExiaoxie"
print(str2.count('xi')) # 2
strip([chars]) 在字符串上执行lstrip()和rstrip()【只能在删除左右两侧】
【例子】
str5 = ' I Love LsgoGroup '
print(str5.lstrip()) # 'I Love LsgoGroup '
print(str5.lstrip().strip('I')) # ' Love LsgoGroup '
print(str5.rstrip()) # ' I Love LsgoGroup'
print(str5.strip()) # 'I Love LsgoGroup'
print(str5.strip().strip('p')) # 'I Love LsgoGrou'
partition(sub) 找到子字符串sub,把字符串分为一个三元组(pre_sub,sub,fol_sub),如果字符串中不包含sub则返回('原字符串','','')。
str5 = ' I Love LsgoGroup '
print(str5.strip().partition('o')) # ('I L', 'o', 've LsgoGroup')
print(str5.strip().partition('m')) # ('I Love LsgoGroup', '', '')
print(str5.strip().rpartition('o')) # ('I Love LsgoGr', 'o', 'up')
- split(str="", num) 不带参数默认是以空格为分隔符切片字符串,如果num参数有设置,则仅分隔num个子字符串,返回切片后的子字符串拼接的列表。
- maketrans(intab, outtab) 创建字符映射的转换表,第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串表示转换的目标。
- translate(table, deletechars="") 根据参数table给出的表,转换字符串的字符,要过滤掉的字符放到deletechars参数中。
【例子】
str7 = 'this is string example....wow!!!'
intab = 'aeiou'
outtab = '12345'
trantab = str7.maketrans(intab, outtab)
print(trantab) # {97: 49, 111: 52, 117: 53, 101: 50, 105: 51}
print(str7.translate(trantab)) # th3s 3s str3ng 2x1mpl2....w4w!!!
【format 格式化函数】{0} 位置参数;{a} 关键字参数;{0:.2f} 保留小数点后两位。
【例子】
str8 = "{0} Love {1}".format('I', 'Lsgogroup') # 位置参数
print(str8) # I Love Lsgogroup
str8 = "{a} Love {b}".format(a='I', b='Lsgogroup') # 关键字参数
print(str8) # I Love Lsgogroup
str8 = "{0} Love {b}".format('I', b='Lsgogroup') # 位置参数要在关键字参数之前
print(str8) # I Love Lsgogroup
str8 = '{0:.2f}{1}'.format(27.658, 'GB') # 保留小数点后两位
print(str8) # 27.66GB
【格式化操作符辅助指令】
符号 功能
m.n m 是显示的最小总宽度,n 是小数点后的位数(如果可用的话)
- 用作左对齐
+ 在正数前面显示加号( + )
# 在八进制数前面显示零('0'),在十六进制前面显示'0x'或者'0X'(取决于用的是'x'还是'X')
0 显示的数字前面填充'0'而不是默认的空格
print('%5.1f' % 27.658) # ' 27.7'
print('%.2e' % 27.658) # 2.77e+01
print('%10d' % 10) # ' 10'
print('%-10d' % 10) # '10 '
print('%+d' % 10) # +10
print('%#o' % 10) # 0o12
print('%#x' % 108) # 0x6c
print('%010d' % 5) # 0000000005
day3:异常处理【20200724】
【Python 标准异常总结(另有Python标准警告总结)】
【try - except 语句】如果在执行try子句的过程中发生了异常,那么 try子句(在关键字try和关键字except之间的语句)余下的部分 将被忽略。如果异常的类型和except之后的名称相符,那么对应的except子句将被执行。最后执行 try语句之后的代码。
使用多个except代码块时,必须坚持对其规范排序,要从最具针对性的异常到最通用的异常。
try:
检测范围
except Exception[as reason]:
出现异常后的处理代码
【例子:OSError打开文件出错;TypeError类型出错;ValueError数值出错】
try:
int("abc")
s = 1 + '1'
f = open('test.txt')
print(f.read())
f.close()
except OSError as error:
print('打开文件出错\n原因是:' + str(error))
except TypeError as error:
print('类型出错\n原因是:' + str(error))
except ValueError as error:
print('数值出错\n原因是:' + str(error))
# 数值出错
# 原因是:invalid literal for int() with base 10: 'abc'
【例子:try-except-else语句(这一异常准确地说应属于KeyError,但由于KeyError是LookupError的子类,且将LookupError置于KeyError之前)】
dict1 = {'a': 1, 'b': 2, 'v': 22}
try:
x = dict1['y']
except LookupError:
print('查询错误')
except KeyError:
print('键错误')
else: ##else语句的存在必须以except语句的存在为前提,在没有except语句的try语句中使用else语句,会引发语法错误。
print(x)
# 查询错误
【例子:异常将被放在一个括号里成为一个元组】一个 except 子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组。
try:
s = 1 + '1'
int("abc")
f = open('test.txt')
print(f.read())
f.close()
except (OSError, TypeError, ValueError) as error:
print('出错了!\n原因是:' + str(error))
# 出错了!
# 原因是:unsupported operand type(s) for +: 'int' and 'str'
【try - except - finally 语句】如果一个异常在try子句里被抛出,而又没有任何的except把它截住,那么这个异常会在finally子句执行后被抛出。
【例子】
def divide(x, y):
try:
result = x / y
print("result is", result)
except ZeroDivisionError:
print("division by zero!")
finally:
print("executing finally clause")
divide(2, 1)
# result is 2.0
# executing finally clause
divide(2, 0)
# division by zero!
# executing finally clause
divide("2", "1")
# executing finally clause
# TypeError: unsupported operand type(s) for /: 'str' and 'str'
【raise语句】Python 使用raise语句抛出一个指定的异常。
【例子】
try:
raise NameError('HiThere')
except NameError:
print('An exception flew by!')
# An exception flew by!
day2:条件语句;循环语句【20200723】
【assert 关键词:“断言”】(1)当这个关键词后边的条件为 False 时,程序自动崩溃并抛出AssertionError的异常。(2)在进行单元测试时,可以用来在程序中置入检查点,只有条件为 True 才能让程序正常工作。
【while - else 循环(for - else 循环)】当while循环正常执行完的情况下,执行else输出;如果while循环中执行了跳出循环的语句,比如 break,将不执行else代码块的内容。
while 布尔表达式:
代码块
else:
代码块
【例子:while - else 循环】
count = 0
while count < 5:
print("%d is less than 5" % count)
count = count + 1
else:
print("%d is not less than 5" % count)
# 0 is less than 5
# 1 is less than 5
# 2 is less than 5
# 3 is less than 5
# 4 is less than 5
# 5 is not less than 5
【例子:for - else 循环】
for num in range(10, 20): # 迭代 10 到 20 之间的数字
for i in range(2, num): # 根据因子迭代
if num % i == 0: # 确定第一个因子
j = num / i # 计算第二个因子
print('%d 等于 %d * %d' % (num, i, j))
break # 跳出当前循环
else: # 循环的 else 部分
print(num, '是一个质数')
# 10 等于 2 * 5
# 11 是一个质数
# 12 等于 2 * 6
# 13 是一个质数
# 14 等于 2 * 7
# 15 等于 3 * 5
# 16 等于 2 * 8
# 17 是一个质数
# 18 等于 2 * 9
# 19 是一个质数
【for 循环】有序序列(如str、list、tuple等)+可迭代对象(如dict)。序列、迭代器、其他支持迭代对象。
dic = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
for key, value in dic.items():
print(key, value, sep=':', end=' ')
# a:1 b:2 c:3 d:4
【enumerate(sequence, [start=0])中的sequence 】一个序列、迭代器或其他支持迭代对象。
lst = list(enumerate(seasons, start=1)) # 下标从 1 开始
print(lst)
# [(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]
【break 和 continue】break语句可以跳出当前所在层的循环;continue终止本轮循环并开始下一轮循环。
【列表推导式】
[ expr for value in collection [if condition] ]
x = [(i, i ** 2) for i in range(6)]
print(x)
# [(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]
【例子】
a = [(i, j) for i in range(0, 3) for j in range(0, 3)]
print(a)
# [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
【例子】
a = [(i, j) for i in range(0, 3) if i < 1 for j in range(0, 3) if j > 1]
print(a)
# [(0, 2)]
【字典推导式】
{ key_expr: value_expr for value in collection [if condition] }
b = {i: i % 2 == 0 for i in range(10) if i % 3 == 0}
print(b)
# {0: True, 3: False, 6: True, 9: False}
day1:变量、运算符与数据类型;位运算【20200722】
【整除(地板除)】//即取商。
【位运算符(三元运算符:x if x < y else y)】
操作符 名称 示例
~ 按位取反 ~4
& 按位与 4 & 5
| 按位或 4 | 5
^ 按位异或 4 ^ 5
<< 左移 4 << 2
>> 右移 4 >> 2
【例子】有关二进制的运算,参见“位运算”部分的讲解。
print(bin(4)) # 0b100
print(bin(5)) # 0b101
print(bin(~4), ~4) # -0b101 -5
print(bin(4 & 5), 4 & 5) # 0b100 4
print(bin(4 | 5), 4 | 5) # 0b101 5
print(bin(4 ^ 5), 4 ^ 5) # 0b1 1
print(bin(4 << 2), 4 << 2) # 0b10000 16
print(bin(4 >> 2), 4 >> 2) # 0b1 1
【内存地址的比较(is, is not) VS 值的比较(==, !=)】
比较的两个变量,指向的都是地址不可变的类型(str等),那么is,is not 和 ==,!= 是完全等价的。
对比的两个变量,指向的是地址可变的类型(list,dict,tuple等),则两者是有区别的。
【例子】比较的两个变量均指向不可变类型。
a = "hello"
b = "hello"
print(a is b, a == b) # True True
print(a is not b, a != b) # False False
【例子】比较的两个变量均指向可变类型。
a = ["hello"]
b = ["hello"]
print(a is b, a == b) # False True
print(a is not b, a != b) # True False
【运算符的优先级】
一元运算符优于二元运算符。例如3 ** -2等价于3 ** (-2)。
先算术运算,后移位运算,最后位运算。例如 1 << 3 + 2 & 7等价于 (1 << (3 + 2)) & 7。
逻辑运算最后结合。例如3 < 4 and 4 < 5等价于(3 < 4) and (4 < 5)。
【Python 里面万物皆对象(object:dir(decimal) 来看其属性和方法)】整型也不例外,只要是对象,就有相应的属性 (attributes) 和方法(methods)。
Python 里面有很多用途广泛的包 (package),用什么你就引进 (import) 什么。包也是对象,也可以用上面提到的dir(decimal) 来看其属性和方法。
【用 bool(X) 来创建变量】,其中 X 可以是
- 基本类型:整型、浮点型、布尔型(X 只要不是整型 0、浮点型 0.0,bool(X) 就是 True,其余就是 False)
- 容器类型:字符串、元组、列表、字典和集合(X 只要不是空的变量,bool(X) 就是 True,其余就是 False)
确定bool(X) 的值是 True 还是 False,就看 X 是不是空,空的话就是 False,不空的话就是 True。
- 对于数值变量,0, 0.0 都可认为是空的。
- 对于容器变量,里面没元素就是空的。
【推荐使用 isinstance(),而非type()】如果要判断两个类型是否相同推荐使用 isinstance()。
- type() 不会认为子类是一种父类类型,不考虑继承关系。
- isinstance() 会认为子类是一种父类类型,考虑继承关系。
【计算机内部使用补码(符号位:最高位为符号位,0表示正数,1表示负数。在位运算中符号位也参与运算)】二进制有三种不同的表示形式:原码、反码和补码,计算机内部使用补码来表示。
Python-Language/02.位运算符.md