strs = 'I like python and java'
one = strs.find('n')
print(one)
two = strs.rfind('n')
print(two)
find是从前往后找,返回成功匹配的第一个字符的位置索引
rfind也是从前往后找,但是返回最后一次成功匹配的字符的位置索引
Python中,打开文件语法为
text = oepn(filePath, 操作方式,编码方式)
常见操作方式:
- ‘r’:读
- ‘w’:写
- ‘a’:追加
常见编码方式:- utf-8
- gbk
lists = [1, 2, 3, 4, 5, 6]
print(lists[6:])
注意区分切片,切片一般指创造新的对象,而基于原列表而创造的切片一旦其切片值超出原列表索引下标则会无法从原列表中获取元素,因此返回一个空的下标
切片是浅拷贝,切片没有索引越界
Python变量的作用域遵循LEGB原则,即
- L:Local,局部作用域,也就是我们在函数中定义的变量;
- E:Enclosing,嵌套的父级函数的局部作用域,即包含此函数的上级函数的局部作用域,但不是全局的;
- G:Globa,全局变量,就是模块级别定义的变量;
- B:Built-in,系统内置模块里面的变量,比如int, bytearray等。
a = [1]
b = 2
c = 1
def fn(lis, obj):
lis.append(b)
obj = obj + 1
return lis, obj
fn(a, c)
print(fn(a, c))
fn(a,c)
:调用了一次fn函数,这时候a变成了[1,2],c还是1,因为函数虽然返回了obj,但是没有赋值,出了函数之后c还是全局变量的那个c;
print(fn(a,c))
:又调用了一次fn函数,过程同上,但是打印的时候打印的是函数的返回值,也就是此时的形参lis和obj的值,而此时lis是[1,2,2],而obj是2。
not 1 and 1
的结果为在Python3中,
not
表示逻辑非,and
表示逻辑与,逻辑非(not
)的运算优先级大于逻辑与(and
)的优先级,则not 1
为False
,则not 1 and 1
结果为False
优先级not>and>or,谐音not at all
not 1 = False
False and 1 = False
str1 = "exam is a example!"
str2 = "exam"
print(str1.find(str2, 7))
在Python3中
strs.find(str, beg=0, end=len(strs))
表示在strs
中返回第一次出现str
的位置下标,beg
表示在strs
中的开始索引,默认为0(此题中为7),end
结束索引,默认为strs的长度。但需要注意的是,返回的索引还是默认从0开始的,并不是beg
的值(beg
只是告诉程序是从该字符串第几个索引开始寻找),因此此题的结果为10
s1 = 'aabbcc'
s2 = 'abc'
count = s1.count(s2)
if count > 0 :
print('s2是s1的子串')
else:
print('s2不是s1的子串')
"""---------------------------"""
s1 = 'aabbcc'
s2 = 'abc'
index = s1.index(s2)
if index > -1:
print('s2是s1的子串')
else:
print('s2不是s1的子串')
"""---------------------------"""
s1 = 'aabbcc'
s2 = 'abc'
find = s1.find(s2)
if find != -1 :
print('s2是s1的子串')
else:
print('s2不是s1的子串')
"""---------------------------"""
s1 = 'aabbcc'
s2 = 'abc'
if s2 in s1:
print('s2是s1的子串')
else:
print('s2不是s1的子串')
正确答案为B。
count()
函数没有匹配到对象返回0
index()
函数没有匹配到对象报错value Error
find()
函数没有匹配到对象返回-1
in
没有匹配到对象返回False
print type(1/2)
- Python2 中除法默认向下取整,因此
1/2 = 0
,为整型。- 而 Python3 中的除法为正常除法,会保留小数位,因此
1/2 = 0.5
,为浮点型(float
)。
class A(object):
pass
class B(A):
pass
b = B()
isinstance()
函数来判断一个对象是否是一个已知的类型,类似type()
。issubclass()
函数用于判断参数是否是类型参数的子类。
a = [1,2,3,1,2,4,6]
进行去重后,得到列表b
,在不考虑列表元素的排列顺序的前提下,下列方法错误的是()b = list(set(a))
"""---------------------------"""
b = {}
b = list(b.fromkeys(a))
"""---------------------------"""
a.sort()
b = []
i = 0
while i < len(a):
if a[i] not in b:
b.append(a[i])
else:
i += 1
"""---------------------------"""
a.sort()
for i in range(len(a)-1):
if a[i] == a[i+1]:
a.remove(a[i])
else:
continue
b = a
D
选项错误原因在于for循环的计数次数是不变的,但是随着a重复元素不断的移除,会导致列表出现IndexError。
n = 1000
while n > 1:
print(n)
n = n / 2
此题题意为:n 从1000开始循环,每次循环执行 n = n / 2,已知 29 = 512,210 = 1024,因此循环的次数为 10次,当循环10次后才会不满足循环条件
sets = {1, 2, 3, 4, 5}
print(sets[2])
程序运行结果为:
python3中,集合不能索引取值,因此会报错:TypeError: ‘set’ object is not subscriptable
集合无序,没有索引访问
num = 1
def fn():
num += 1
return lambda:print(num)
x = fn()
x()
虽然在函数外部声明num 为全局变量,但若函数体内对num变量重新赋值,其结果会使得函数内部屏蔽了外面的全局变量num,此时语句num += 1就会抛出异常,即num变量没有先赋值就直接引用了。
dicts = {'one': 1, 'two': 2, 'three': 3}
tmp = dicts.copy()
tmp['one'] = 'abc'
print(dicts)
print(tmp)
字典数据类型的
copy
函数,当简单的值替换的时候,原始字典和复制过来的字典之间互不影响,但是当添加,删除等修改操作的时候,两者之间会相互影响。
所以新字典的值的替换对原字典没有影响
strs = '123456'
print(strs.find('9'))
find
和rfind
在查不到的时候-1index
和rindex
在查不到时都返回value error 所以编程时建议使用find
urllib.quote(line.decode("gbk").encode("utf-16"))
注意审题,问的是解码顺序不是编码顺序
def fun(a=(), b=[]):
a += (1, )
b.append(1)
return a, b
fun()
print(fun())
Python的默认参数只在函数定义时被赋值一次,而不会每次调用函数时又创建新的引用。这意味着,函数定义完成后,默认参数已经存在固定的内存地址了,如果使用一个可变的默认参数并对其进行改变,那么以后对该函数的调用都会改变这个可变对象,而默认参数如果是不可变对象,不存在该问题,因此正确答案为A选项。
注意审题,两次函数调用
strs = ['a', 'ab', 'abc', 'python']
y = filter(lambda s: len(s) > 2, strs)
tmp = list(map(lambda s: s.upper(), y))
print(tmp)
filter
中的条件是pass的条件
filter输出是一个filter对象,可以通过list
,tuple
等工厂函数转换为对应的数据类型
Python 中的 tuple 结构为 “不可变序列”,用小括号表示。为了区别数学中表示优先级的小括号,当 tuple 中只含一个元素时,需要在元素后加上逗号。
dicts = {'one': 1, 'two': 2, 'three': 3}
print(dicts['one'])
print(dicts['four'])
py3 访问不存在的索引或key:
py3 切片越界(索引为自然数情况):
''
空字符b = 1
def fn():
nonlocal b
b = b + 1
print(b)
fn()
# ------------------------------------
tup = (('onion', 'apple'), ('tomato', 'pear'))
for _, fruit in tup:
print(fruit)
# ------------------------------------
a = [b for b in range(10) if b % 2 == 0]
print(b) #
# ------------------------------------
lis = [1, 2, 'a', [1, 2]]
set(lis)
- A选项,变量b属于全局变量,所以应该使用global声明而不是nonlocal;
- B选项,可以使用_作为占位符,所以B选项不会报错;
- C选项,python3.x中,使用列表生成式,中间变量b在生成列表后被销毁,因此再次使用变量b会报错;
- D选项,集合元素不能是列表这类不可散列对象,因此会报错。
- A. 函数可以没有return
- B. 看起来return可以返回多个值,但其实并不是,多个值返回是通过tuple实现的
- C. 在Python中是没有Null这个数据类型的,返回的应该是None
def fn():
t = []
i = 0
while i < 2:
t.append(lambda x: print(i * x, end=","))
i += 1
return t
for f in fn():
f(2)
函数
fn
存在闭包现象,自由变量是i
,由于python闭包采用延迟绑定,也就是当调用匿名函数时,循环早已结束,此时i
的值为2,所以输出结果都为2*2=4,正确答案为A。
a = '123'
b = '123'
a,b
为字符串不可变类型,所以指向相同地址,所以a is b
+is指地址相同
==
内容相同
===
内容和格式相同
a+b=‘123123’
a==123
,字符和int不相同
strs = ' I like python '
one = strs.strip()
print(one)
two = strs.rstrip()
print(two)
split
: 字符串首尾默认存在空白字符,所以当分隔符在字符串首尾的时候,有多少个分隔符就会产生多少个空格- strip():删除首尾空格;
- rstrip():仅删除右空格;
strs = ' I like python '
one = strs.split(' ')
two = strs.strip()
print(one) # ['', 'I', 'like', 'python', '']
print(two) # I like python
strs = ' I like python '
one = strs.split(' ')
two = strs.strip()
print(one) # ['', '', '', '', '', '', '', '', 'I', 'like', 'python']
print(two) # I like python
names = ["Andrea", "Aaslay", "Steven", "Joa"]
lists = []
for name in names:
if name.count('a') >= 2:
lists.append(name)
print(lists)
此题题意为:从名字的字符数组中找出名字中包含字母 ‘a’ 个数大于等于2个名字列表合集
首先对名字的字符数组进行遍历获取每一个名字,再通过 count() 函数判断名字中是否包含字母 ‘a’ 个数大于等于2个,将符合要求的名字字符存放到lists数组中(需要注意 ‘a’ 是区分大小写的),最后输出的 lists = [‘Aaslay’]
dicts = {}
dicts[([1, 2])] = 'abc'
print(dicts)
在Python3中,只有当元组内的所有元素都为不可变类型的时候,才能成为字典的key,因此程序运行过程中会报错:TypeError: unhashable type: ‘list’
lis = ['apple', 'lemon', 'pear', 'peach']
def fn(x):
return x[::-1]
lis.sort(key=fn, reverse=True)
print(lis)
函数
fn
的作用就是将字符反转,比如fn("apple")
得到 “elppa”。列表中元素按照fn函数规则,进行降序排列,此时的列表元素经过函数规则后:[‘elppa’,‘nomel’,‘raep’,hcaep],进行降序排列如下:[‘raep’, ‘nomel’, ‘hcaep’, ‘elppa’],但列表元素并不会改变,所以结果为D。
_foo
不能直接用于from module import *
__foo
解析器用_classname__foo
来代替这个名字,以区别和其他类相同的命名__foo__
代表python里特殊方法专用的标识__foo
可以直接用于from module import *
python中主要存在四种命名方式:
object
:公用方法_object
:半保护,被看作是“protect”,意思是只有类对象和子类对象能访问到这些变量,在模块或类外不可以使用,不能用from module import *
导入。
__object
是为了避免与子类的方法名称冲突, 对于该标识符描述的方法,父类的方法不能轻易地被子类的方法覆盖,他们的名字实际上是_classname__methodname
。__ object
:全私有,全保护,私有成员“private”,意思是只有类对象自己能访问,连子类对象也不能访问到这个数据,不能用from module import *
导入。__ object__
:内建方法,用户不要这样定义
①环境变量中的PYTHONPATH
②内建模块
③python安装路径
④当前路径,即执行Python脚本文件所在的路径
其中查找顺序正确的一组是()
python搜索模块的顺序为:内建模块>当前路径,即执行Python脚本文件所在的路径>环境变量中的PYTHONPATH>python安装路径,故答案为C。
内建模块(built-in) > 当前路径(./) > 环境变量 > Python安装路径
lis = [1,3,2]
a = id(lis)
lis = sorted(lis)
b = id(lis)
print(a==b)
print("======================")
lis = [1,3,2]
a = id(lis)
lis += [4,5]
b = id(lis)
print(a==b)
print("======================")
tup = (1,3,2)
a = id(tup)
tup += (4,5)
b = id(tup)
print(a==b)
print("======================")
tup = (1,3,2)
a = id(tup)
tup = sorted(tup)
b = id(tup)
print(a==b)
使用
sorted()
进行排序会生成新的序列,生成的新序列和原序列id值必然不同。对于可变对象,sorted()进行排序时原序列也发生变化,而本题A中用lis保存了生成的新序列,因此AD选项输出结果均为False;对于+=操作,如果是可变对象,则操作前后序列的id值不变,如果是不可变对象,则操作前后序列的id值改变,故B正确。
strs = ' I like python '
one = strs.split(' ')
two = strs.strip()
print(one)
print(two)
当分割的地方有空格, 那么分割的时候就会保留空格。
a = 1
b = 2
a,b = b,a
print("================")
a,*b,c = range(5)
print(a,b,c)
print("================")
lis = ['1','2']
a,b = list(map(int,lis))
print(a,b)
print("================")
tup = (1,(2,3))
a,b,c = tup
print(a,b,c)
ABCD四个选项的程序都是可迭代元素拆包问题。
- A选项是两数交换的优雅写法;
- B选项,python允许使用*来处理剩下的参数;
- C选项是关于列表的拆包,让可迭代对象的元素一一赋值给对应的变量;
- D选项会抛出异常,这是因为对应变量不满足元组的嵌套结构,正确的写法应该是a,(b,c) = tup
str = "Hello,Python";
suffix = "Python";
print (str.endswith(suffix,2));
str.endswith(suffix, start, end]) 用于判断字符串是否以指定后缀结尾,如果以指定后缀结尾返回True,否则返回False。
可选参数"start"与"end"为检索字符串的开始与结束位置。
- 表示复数的语法是real + image j
- 实部和虚部都是浮点数
- 虚部的后缀可以是 “j” 或者 “J”
- 复数的 conjugate 方法可以返回该复数的共轭复数
print r"\nwoow"
woow
r"\nwoow"
\nwoow
r
and then newline then the text: woow
r
then the text like this: nwoow
Python 中字符串的前导
r
代表原始字符串标识符,该字符串中的特殊符号不会被转义,适用于正则表达式中繁杂的特殊符号表示。例子如下:
print("\n This is a test paragraph")
print("\\n This is a test paragraph")
print(r"\\n This is a test paragraph")
"""
This is a test paragraph
\n This is a test paragraph
\\n This is a test paragraph
"""
res = []
for i in 'python':
if i == 'h':
continue
res.append(i)
print(''.join(res))
此题中的
continue
跳出本次循环,继续下一次循环,即为跳出i == 'h'
时,因此res = ['p','y','t','o','n']
,最后打印的结果采用join函数
连接res
中的字符,输出的结果为'pyton'
num = 1
def fn():
num += 1
return lambda:print(num)
x = fn()
x()
虽然在函数外部声明num 为全局变量,但若函数体内对num变量重新赋值,其结果会使得函数内部屏蔽了外面的全局变量num,此时语句num += 1就会抛出异常,即num变量没有先赋值就直接引用了。
list = ['1', '2', '3', '4', '5']
print list[10:]
如果是索引访问,会导致IndexError,但本体考的是切片,切片操作时如果索引越界不会导致IndexError,只是返回一个空序列,这里返回空列表 []。
strs = 'abcd12efg'
print(strs.upper().title())
str.title()
方法返回"标题化"的字符串,就是说所有单词的首个字母转化为大写,其余字母均为小写
注意,如果字符串是乱打的,那么中间的数字会将其进行分割。
strs = "This is a test paragraph."
print("1:", strs.upper()) # 所有字母大写
print("2:",strs.lower()) # 所有字母小写
print("3:",strs.title()) # 单词的首字母大写
print("4:",strs.capitalize()) # 字符串的首字母大写
print("-" * 30)
print("5:",strs.upper().title())
print("6:",strs.lower().title())
print("-" * 30)
print("7:",strs.upper().capitalize())
print("8:",strs.lower().capitalize())
"""
1: THIS IS A TEST PARAGRAPH.
2: this is a test paragraph.
3: This Is A Test Paragraph.
4: This is a test paragraph.
------------------------------
5: This Is A Test Paragraph.
6: This Is A Test Paragraph.
------------------------------
7: This is a test paragraph.
8: This is a test paragraph.
"""
粗心了,D也是正确的。
nums = set([1,2,2,3,3,3,4])
print len(nums)
set中的数据不能重复,会自动去除重复的值
tmp = dict.fromkeys(['a', 'b'], 4)
print(tmp)
Python3
dict.fromkeys(seq, value)
函数用于创建一个新字典,以序列seq
中元素做字典的键,value
为字典所有键对应的初始值,该方法返回一个新字典。
import math
def sieve(size):
sieve= [True] * size
sieve[0] = False
sieve[1] = False
for i in range(2, int(math.sqrt(size)) + 1):
k= i * 2
while k < size:
sieve[k] = False
k += i
return sum(1 for x in sieve if x)
print(sieve(10000000000))
这道题,不能硬做,直接拿到python上跑,肯定会jj,要读懂代码的内涵。当然也可以先跑几个简单的例子,比如跑print(sieve(10))或者print(sieve(100))等等。其实,如果学过素数筛的就能很快看出,这是一道素数筛选的题。所以我们只要上网直接搜一下10000000000以内的素数个数就可以了。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FA0Nbzn2-1658027312766)(./imgs_markdown/2022-07-14-14-43-34.png)]
class Animal:
def __init__(self,color):
self.__color = color
@property
def color(self):
return self.__color
@需要填写的修饰器名称
def color(self,color):
self.__color = color
animal = Animal('red')
print(animal.color)
animal.color = 'white'
print(animal.color)
程序创建了一个animal对象,然后访问和修改对象的私有属性
__color
,@property
装饰器,相当于一个get方法
,用于获取私有属性值,因此需要补充的是setter
方法。
python对于setter装饰器的语法是:@方法名.setter
,因此答案为C选项。
import random
def foo(n):
random.seed()
c1 = 0
c2 = 0
for i in range(n):
x = random.random()
y = random.random()
r1 = x * x + y * y
r2 = (1 - x) * (1 - x) + (1 - y) * (1 - y)
if r1 <= 1 and r2 <= 1:
c1 += 1
else:
c2 += 1
return c1 / c2
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t896m7uk-1658027312767)(./imgs_markdown/2022-07-14-14-57-38.png)]
dicts = {}
dicts[(1, 2)] = ({3, (4, 5)})
print(dicts)
Python3中,对字典中添加键/值,题目中的字典键为 (1,2),对应的值为 ({3, (4, 5)})
需要注意的是:python中的set是以元素的哈希值确定位置
lists = [1, 2, 2, 3, 3, 3]
print(lists.count(3))
print(lists.pop())
lists.pop()
print(lists)
把list理解为是一个堆栈,堆栈遵循先进后出原则,所以pop()默认是从末尾弹出!
str1 = "exam is a example!"
str2 = "exam"
print(str1.find(str2, 7))
在Python3中 strs.find(str, beg=0, end=len(strs))表示在strs中返回第一次出现str的位置下标,beg表示在strs中的开始索引,默认为0(此题中为7),end结束索引,默认为strs的长度,因此此题的结果为10
dicts = {'one': 1, 'two': 2, 'three': 3}
print(dicts['one'])
print(dicts['four'])
直接取元素的idx就会报错,而切片一般不会报错(返回一个空列表或空字典)
for i in range(5):
if i == 2:
pass
print(i)
别被迷惑
"""-----------------------选项A-----------------------"""
class Rect:
def __init__(self, width, height):
self.width = width
self.height = height
@property
def area(self):
return self.height * self.width
rect = Rect(10, 20)
rect.area() # TypeError: 'int' object is not callable
"""-----------------------选项B-----------------------"""
a = 0
def fun():
a += 1
print(a)
fun() # UnboundLocalError: local variable 'a' referenced before assignment
"""-----------------------选项C-----------------------"""
class Animal:
def __init__(self, color="白色"):
Animal.color = color
def get_color(self):
print("Animal的颜色为", Animal.color)
class Cat(Animal):
def __init__(self):
pass
cat = Cat()
cat.get_color(
) # AttributeError: type object 'Animal' has no attribute 'color'
"""-----------------------选项D-----------------------"""
class Cat:
def __init__(self, color="白色"):
self.__color = color
cat = Cat("绿色")
print(cat._Cat__color) # 绿色
- A选项,使用property会将方法转为属性,因此rect.area()应该改为rect.area
- B选项,当给作用域中的一个变量赋值时,Python 会自动的把它当做是当前作用域的局部变量,从而会隐藏外部作用域中的同名变量,因此a += 1会报错
- C选项,子类若有定义
__init__()
函数时,将不会自动继承父类的构造函数,因此在调用父类的get_color()函数时,会出现Animal找不到属性color,修改时只需在子类的__init__()
函数中添加语句:super().__init__()
- D选项,尽管color属性为私有属性,但是在类外部使用时,仍可以通过
实例名._类名__xxx
来访问。
class Animal:
def __init__(self, color="白色"):
Animal.color = color
def get_color(self):
print("Animal的颜色为", Animal.color)
class Cat(Animal):
def __init__(self):
super().__init__()
# class Cat(Animal):
# pass # 这也可以运行的!
cat = Cat()
cat.get_color() # AttributeError: type object 'Animal' has no attribute 'color'
a = 100
b = 14
print(divmod(a, b))
python3中,divmod将除法运算和取余运算结合在一起,结果返回一个tuple(元组)(商和余数)
strs = 'abbacabb'
print(strs.strip('ab'))
strs.strip('ab')
中的'ab'
表示的是一种集合,这里是指:[ab,ba,aa,bb,aaa,bbb,abb,baa]等;
strs两端,只要是包含了上述集合中的任何一个,都删除。
需要注意的是,strip删除的是第一个单词,看下面的例子就可以理解了:
str_1 = "abc bac cab bac acb cba"
print(f"|{str_1.strip('abc')}|")
str_2 = "abcbaccabbacacbcba"
print(f"|{str_2.strip('abc')}|")
print("-" * 30)
str_3 = "abc\nbac\ncab\nbac\nacb\ncba" # \t会将string分割为不同的单词
print(f"|{str_3.strip('abc')}|")
print("-" * 30)
str_4 = "abc\tbac\tcab\tbac\tacb\tcba" # \t也会将string分割为不同的单词
print(f"|{str_4.strip('abc')}|")
print("-" * 30)
str_5 = "abc,bac,cab,bac,acb,cba" # ,也会将string分割为不同的单词
print(f"|{str_5.strip('abc')}|")
str_6 = "abc, bac, cab, bac, acb, cba" # , 也会将string分割为不同的单词
print(f"|{str_6.strip('abc')}|")
str_7 = 'abbacabb'
print(f"|{str_7.strip('ab')}|")
"""
| bac cab bac acb |
||
------------------------------
|
bac
cab
bac
acb
|
------------------------------
| bac cab bac acb |
------------------------------
|,bac,cab,bac,acb,|
|, bac, cab, bac, acb, |
|c|
"""
class Vector:
__slots__='x','y'
def __init__(self):
pass
class Vector3d(Vector):
__slots__='x','z'
def __init__(self):
pass
vector = Vector()
vector3d = Vector3d()
- python中凡是 “__” 开头的变量,都是私有变量,私有变量继承需要定义同名变量,因此A错误
__slots__
是python类中的特殊变量,用于限制实例对象的属性,如__slots__=‘x’,‘y’,那么实例对象的属性就只能从这些里面找,因此它起的是限制效果而非自动获得,因此B错误。- 定义同名变量后子类继承父类的
__slots__
,从而支持xyz,因此C错- 选D
class Vector:
__slots__ = 'x', 'y'
def __init__(self):
pass
class Vector3d(Vector): # 既然Vector3d已经继承Vector, 那么__slots__中就已经有x, y了
__slots__ = 'x', 'z' # 这句话的意思就是重新给Vector3d这个类定义了2个类属性,这里定义的x会覆盖从父类继承的x
def __init__(self):
pass
vector = Vector()
vector3d = Vector3d()
vector.x = 10
vector.y = 20
print(vector.x, vector.y) # 10 20
# 我们再给它其他的属性
try:
vector.z = 30
print(vector.z) # AttributeError: 'Vector' object has no attribute 'z'
except:
pass
vector3d.x = 10
vector3d.y = 20
vector3d.z = 30
print(vector3d.x, vector3d.y, vector3d.z) # 10 20 30
def f(a, b):
if b == 0:
return a
else:
return f(b, a%b)
a, b = input(“Enter two natural numbers: ”)
print f(a, b)
a % b 是求余数
辗转相除法,又称欧几里得算法,以除数和余数反复做除法运算,当余数为 0 时,取当前算式除数为最大公约数。
dic = {‘a’:1,'b':2}
,下列选项中,做法错误的是()lis1 = ['a','b']
lis2 = [1,2]
dic = dict(zip(lis1,lis2))
print(dic)
tup = ('a','b')
lis = [1,2]
dic = {tup:lis}
print(dic)
dic = dict(a=1,b=2)
print(dic)
lis = ['a','b']
dic = dict.fromkeys(lis)
dic['a'] = 1
dic['b'] = 2
print(dic)
A: {'a': 1, 'b': 2}
B: {('a', 'b'): [1, 2]}
C: {'a': 1, 'b': 2}
D: {'a': 1, 'b': 2}
import copy
a = [1, 2, 3, 4, ['a', 'b']]
b = a
c = copy.copy(a)
d = copy.deepcopy(a)
a.append(5)
a[4].append('c')
首先我们看看a这个list在电脑里实际的存储情况:
们再看看b的情况,b实际上和a指向的是同一个值,就好比人的大名和小名,只是叫法不同,但还是同一个人:
接下来再看看c的情况,c的情况和a.copy()的情况是一样的,都是我们所谓的浅拷贝(浅复制),浅拷贝只会拷贝父对象,不会拷贝子对象,通俗的说就是只会拷贝到第二层:
若父对象发生变化,c不会变化,因为它已经复制的所有父对象,假如子对象发生变化则c会变,比如c[4]和a[4]实际都是一个变量list,他们都指向子对象,若子对象发生变化,他们必然都变化,比如变成[“a”,“d”],那它们指向的值也就变成了a、d。
再看看d的情况,这就是我们所说的深复制,不管a进行什么操作,都不会改变d了,他们已经指向不同的值(这里是指在内存中存储的位置不同了)。
dicts = {'one': 1, 'two': 2, 'three': 3}
tmp = dicts.copy()
tmp['one'] = 'abc'
print(dicts)
print(tmp)
字典数据类型的copy函数,当简单的值替换的时候,原始字典和复制过来的字典之间互不影响,但是当添加,删除等修改操作的时候,两者之间会相互影响。
所以新字典的值的替换对原字典没有影响
names = ["Andrea", "Aaslay", "Steven", "Joa"]
lists = []
for name in names:
if name.count('a') >= 2:
lists.append(name)
print(lists)
Python严格区分大小写,所以答案选D不选C
a = [1, 2, 3]
和b = [1, 2, 4]
,那么id(a[1])==id(b[1])
的执行结果 ()id(object)是python的一个函数用于返回object的内存地址。但值得注意的是,python 为了提高内存利用效率会对一些简单的对象(如数值较小的int型对象,字符串等)采用重用对象内存的办法。
python中对于小整数对象有一个小整数对象池,范围在[-5,257)之间。对于在这个范围内的征数,不会新建对象,直接从小整数对象池中取就行。
在python3.6中对于小整数对象有一个小整数对象池,范围不止在[-5,257)之间。我试了百万以上的数地址都是相同的(在解释器中是,在开发工具中不是)
class Base(object):
count = 0
def __init__(self):
pass
b1 = Base()
b2 = Base()
b1.count = b1.count + 1
print(b1.count,end=" ")
print(Base.count,end=" ")
print(b2.count)
count为类属性,类属性可以为实例属性提供默认值,也就是,当使用b1.count时,count成了b1对象的实例属性,实例属性不会影响到类属性的值,也不会影响到其他实例属性,所以对b1.count进行修改时只会影响自身,Base.count和b2.count的值仍为0。
count是类变量
- 通过类名修改类变量,会作用到所有的实例化对象
- 通过类对象是无法修改类变量的。通过类对象对类变量赋值,其本质将不再是修改类变量的值,而是在给该对象定义新的实例变量
class Foo():
def __init__(self):
pass
def __getitem__(self,pos):
return range(0,30,10)[pos]
foo = Foo()
- 若要表现像个序列,必须满足序列的两个方法:①
__len__
和②__getitem__
,由于Foo类中没有实现__len__,因此不满足序列协议,foo对象不像序列,A错误;- foo对象没有定义
__len__
方法,不能使用它来查看对象个数,B错误;
对对象的迭代需要调用__iter__
,如果没有定义该方法,python会调用__getitem__(),让迭代和in运算符可用,因此foo是可迭代的,C正确;
根据索引访问对象元素,会调用__getitem__()
,因此D错误。
foo = Foo()
print(f"foo对象: {foo}") # <__main__.Foo object at 0x0000022E78DA4BE0>
try:
print(f"len(foo): {len(foo)}")
except:
print("不可以通过len(foo)查看对象foo的元素个数") # 不可以通过len(foo)查看对象foo的元素个数
for i in foo: # 0 \n 10 \n 20
print(i)
print(f"foo[0]: {foo[0]}") # foo[0]: 0
python中的标识符:
- 第一个字符必须是字母表中字母或下划线
_
。- 标识符的其他的部分由字母、数字和下划线组成。
- 标识符对大小写敏感。
- 不可以是python中的关键字,如False、True、None、class等。
注意:self不是python中的关键字。类中参数self也可以用其他名称命名,但是为了规范和便于读者理解,推荐使用self。
print('\n'.join(['a', 'b', 'c']))
Python中
join()
方法用于将序列中的元素以指定的字符连接生成一个新的字符串。
join()方法语法:str.join(sequence)
print('\n'.join(['a', 'b', 'c']))
print("-----------------")
print('-'.join(["a", "b", "c"]))
"""
a
b
c
-----------------
a-b-c
"""
res = []
for i in 'python':
if i == 'h':
continue
res.append(i)
print(''.join(res))
此题中的
continue
跳出本次循环,继续下一次循环,即为跳出i == 'h'
时,
因此res = ['p','y','t','o','n']
,最后打印的结果采用 join 函数连接res中的字符,输出的结果为 ‘pyton’
直接print(res)是不带''
的,因此加了join后就会带''
res = []
for i in 'python':
if i == 'h':
continue
res.append(i)
print(res) # ['p', 'y', 't', 'o', 'n']
[print(i, end=" ") for i in res] # p y t o n
print("") # \n
print(''.join(res)) # pyton -> 其实就是不用任何东西连接
print('-'.join(res)) # p-y-t-o-n
counter = 1
def doLotsOfStuff():
global counter
for i in (1, 2, 3):
counter += 1
doLotsOfStuff()
print counter
最后要注意第 5 行的坑,是 counter += 1 而不是 counter += i ,因此答案是 4 而不是 7,选答案 C。
n = 1000
while n > 1:
print(n)
n = n / 2
此题题意为:n 从1000开始循环,每次循环执行 n = n / 2,已知 2^9 = 512,2^10 = 1024,因此循环的次数为 10次,当循环10次后才会不满足循环条件
其中查找顺序正确的一组是()
记住,别再错了
t1 = (1,2,3)
t2 = t1[:]
print(t1 is t2)
lis1 = [1,2,3]
lis2 = lis1[:]
print(id(lis1)==id(lis2))
s1 = '123'
s2 = '123'
print(s1 is s2)
a = 123
b = 123
print(id(a) == id(b))
- 由①数字,②字符和③下划线组成的短字符串以及④[-5,256]内的整数存在内存驻留,将其赋值给多个不同的对象时,内存中只有一个副本,多个对象共享该副本,故CD选项结果均为True;
- 对于A选项,元组的[:]并不会创建副本,而是返回同一个对象的引用,所以t1和t2的id值均一样,结果为True;
- 对于B选项,列表的[:]会创建副本,其id值发生改变,结果为False。
def fun(a=(), b=[]):
a += (1,)
b.append(1)
return a, b
fun()
print(fun())
Python的默认参数只在函数定义时被赋值一次,而不会每次调用函数时又创建新的引用。这意味着,函数定义完成后,默认参数已经存在固定的内存地址了,如果使用一个可变的默认参数并对其进行改变,那么以后对该函数的调用都会改变这个可变对象,而默认参数如果是不可变对象,不存在该问题,因此正确答案为A选项。
a = ()
a += (1,)
print(f"a: {a}") # a: (1,)
b = ()
b += (1, 2, 3, 4, 5, 6)
print(f"b: {b}") # b: (1, 2, 3, 4, 5, 6)
c = []
c += [1,]
print(f"c: {c}") # c: [1]
d = []
d += [1, 2, 3, 4, 5, 6, 7]
print(f"d: {d}") # d: [1, 2, 3, 4, 5, 6, 7]
a = range(100)
print(a) # range(0, 100)
print(a[10]) # 10
print(a[:]) # range(0, 100)
print(a[1:2]) # range(1, 2)
print(a[-3]) # 97
func = lambda x:x%2
result = filter(func, [1, 2, 3, 4, 5])
print(list(result))
filter(function, iterable)
,filter
函数是python中的高阶函数, 第一个参数是一个筛选函数, 第二个参数是一个可迭代对象, 返回的是一个生成器类型, 可以通过next获取值. 这里大致讲述下原理, filter()把传入的function依次作用于iterable的每个元素, 满足条件的返回true, 不满足条件的返回false, 通过true还是false决定将该元素丢弃还是保留.
所以对2和4取余为0舍弃1.3.5取余为1为真保留;
通过下面的例子我们可以看到filter函数会保留什么样的数值:
func = lambda x: x
result = filter(func, [True, False, -3, -2, -1, 0, 1, 2, 3, 4, 5])
print(list(result)) # [True, -3, -2, -1, 1, 2, 3, 4, 5]
可以看到,filter函数不保留的有:
其他的都会保留
a = [['1','2'] for i in range(2)]
b = [['1','2']]*2
a[0][1] = '3'
b[0][0] = '4'
print(a,b)
在python中, 如果用一个列表a乘一个数字会得到一个新的列表b, 这个新的列表b的元素是a的元素重复n次(可以理解
*
是浅拷贝)。
tup = (1,2,[3,4]) # ①
tup[2]+=[5,6] # ②
- tup[2]是列表,列表是可变对象,对于可变对象,执行+=后并不会改变其id值,A错误;
- 执行②时会抛出异常,“+=”的执行顺序是先对[3,4]执行+操作,其结果为[3,4,5,6],然后再执行”=“,此时会抛出异常,这是因为元组不允许元素的引用被重新赋值,尽管赋值后列表的id是不变的,若改成tup[2].extend([5,6])就不会抛出异常。
dicts = {'one': 1, 'two': 2, 'three': 3}
tmp = dicts.copy()
tmp['one'] = 'abc'
print(dicts)
print(tmp)
对于字典、列表、集合来说,浅拷贝只拷贝对应的内存地址,而深拷贝会完全复制拷贝一份新的。对于字符串、数字这些,浅拷贝跟深拷贝都是一样拷贝一份新的。
old_dicts = {'name': tom, 'age': 18, 'like': [1,2,3]}
- 浅拷贝
new_dicts = old_dicts.copy()
修改name
或者age
时,不会相互影响,而修改like时,会互相影响。- 深拷贝
new_deep_dicts = old_dicts.deepcopy()
就是完完全全复制了一份新的,从头复制到尾,是相互独立的两个字典了,不管怎么修改都不会影响到对方
import re
str1 = "Python's features"
str2 = re.match( r'(.*)on(.*?) .*', str1, re.M|re.I)
print str2.group(1)
re
模块实现正则的功能:
re.match(正则表达式, 要匹配的字符串, [匹配模式])
str1 = "Python's features"
r'(.*)on(.*?) .*'
r
表示后面的字符串是一个普通字符串(比如\n
会译为\
和n
,而不是换行符)()
符号包住的数据为要提取的数据,通常与.group()
函数连用。正则表达式的规则:
.
匹配单个任意字符*
匹配前一个字符出现0次或无限次?
匹配前一个字符出现0次或1次(.*)
提取的数据为str1字符串中on左边的所有字符,即Pyth
(.*?)
提取的数据为str1中on右边,空格前面,即's
.group(0)
输出的是匹配正则表达式整体结果
.group(1)
列出第一个括号匹配部分.group(2)
列出第二个括号匹配部分class Rectangle:
__count = 0
def __init__(self,width,height):
Rectangle.__count += 1
self.__width = width
self.__height = height
@property
def area(self):
return self.__height * self.__width
rectangle = Rectangle(200,100)
rectangle.area()
来访问area属性__count
的作用是为了统计创建对象的个数__width
和__height
为私有变量,所以在类外不可能访问__width
和__height
属性
- 使用
@property
将方法转为属性,该属性为只读属性,只可访问但是不可以修改,使用对象.方法名
来访问该属性,但是方法不能再加小括号,故AB选项说法均错误;- 变量
__count
是类的私有变量,由于每次创建对象时,其值自增1,所以可以用来统计创建对象的个数,C正确;- 虽然
__height
和__width
为私有变量,不能在类外直接使用对象名.属性名
来访问,但是,仍可以使用rectangle._Rectangle__width
和rectangle._Rectangle__height
来强制访问,故D错误。
sets = {1, 2, 3, 4, 5}
print(sets[2])
python3中,集合不能索引取值,因此会报错:
TypeError: 'set' object is not subscriptable
集合无序,没有索引访问
strs = 'I like python and java'
print(strs.replace('I', 'Your'))
print(strs.replace('a', '*', 2))
str.replace(old, new, count=-1)
是用来替换字符/字符串的,count是替换的最大次数,如果不指定默认为-1,表示替换所有。
sizes = ['S','M']
colors = ['white','black']
shirts = [(size,color) for color in colors for size in sizes]
print(shirts)
列表推导式中在最左边的是最外层循环,越往右循环越靠内
sizes = ['S','M']
colors = ['white','black']
shirts = [(size,color) for color in colors for size in sizes] # for循环是从左到右的
print(shirts)
shirts = []
for color in colors:
for size in sizes:
shirts.append((size, color))
print(shirts)
__new__
是一个静态方法,而__init__
是一个实例方法__new__
方法会返回一个创建的实例,而__init__
什么都不返回__new__
返回一个cls的实例时,后面的__init__
才能被调用__new__
,初始化一个实例时用__init__
根据官方文档:
__init__
方法为初始化方法, __new__
方法才是真正的构造函数。__new__
方法默认返回实例对象供__init__
方法、实例方法使用。__init__
方法为初始化方法,为类的实例提供一些属性或完成一些动作。__new__
方法创建实例对象供__init__
方法使用,__init__
方法定制实例对象。__new__
是一个静态方法,而__init__
是一个实例方法。
__new__
是真正的构造方法,所以它是属于cls自身的,因此是一个静态方法;而__init__
方法是针对生成的不同的类对象,所以是实例方法。