pk哥肝了一个月,从两本书《Python基础教程(第3版)》和《流畅的Python》里把知识点进行了汇总,整理成了 100 道 Python习题, Python 100题我已经整理成了 PDF 文档,需要文档的可以关注下方公众号「Python知识圈」并回复:“100” 获取文档。
关注后回复:“100” 获取 pdf 文档
Python基础习题
怎么计算2的3次方
解法1:直接用运算符 **
>>> 2**3
8
解法2:用函数 pow
>>> pow(2,3)
8
怎么找出序列中的最大最小值?
用内置函数 max 和 min
>>> l = (123, 888, 666)
>>> max(l)
888
>>> min(l)
123
怎么将字符列表转为字符串
用 join 方法,合并序列的元素
>>> l = ['Python', 'Circle', 'is', 'ok']
>>> j = ' '.join(l)
>>> j
'Python Circle is ok'
怎么快速打印出包含所有 ASCII 字母(大写和小写)的字符串
用 string 模块的方法
>>> import string
>>> string.ascii_letters
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
怎么让字符串居中
用字符串中的 center 方法,他会在两边自动填充字符(默认为空格),让字符串居中
>>> k = '更多精彩,请关注公众号「Python知识圈」'
>>> k.center(50)
' 更多精彩,请关注公众号「Python知识圈」 '
>>> k.center(50, '*')
'**************更多精彩,请关注公众号「Python知识圈」**************'
怎么在字符串中找到子串
用 find 方法,如果找到,就返回子串的第一个字符的索引,否则返回 -1
>>> ss = 'I Love Python'
>>> ss.find('I')
0
>>> ss.find('Python')
7
怎么让字符的首字母大写,其他字母小写
解法1:用 title 方法。
>>> ss = 'i love python'
>>> ss.title()
'I Love Python'
解法2:用 string 模块里的 capwords 方法。
>>> import string
>>> ss = 'i love python'
>>> string.capwords(ss)
'I Love Python'
怎么清空列表内容
解法1:用 clear 方法
>>> l = [1, 2, 3]
>>> l.clear()
>>> l
[]
解法2:用切片赋值的方法
>>> k = [1, 2, 3]
>>> k[:] = []
>>> k
[]
怎么计算指定的元素在列表中出现了多少次?
用 count 方法
>>> l = ['i', 'am', 'ok', 'ok']
>>> l.count('ok')
2
怎么在列表末尾加入其它元素
用 extend 方法
>>> l = [1, 2, 3]
>>> j = [4, 5, 6]
>>> l.extend(j)
>>> l
[1, 2, 3, 4, 5, 6]
extend 和列表相加的区别?
两者看起来效果一致
>>> l = [1, 2, 3]
>>> j = [4, 5, 6]
>>> l + j
[1, 2, 3, 4, 5, 6]
extend 是直接在 l 列表里加入元素,相加会生成一个新元素,并不会对 l 做修改。
怎么查找列表中某个元素第一次出现的索引,从 0 开始
用 index 方法
>>> l = ['are', 'you', 'ok']
>>> l.index('you')
1
怎么将一个对象插入到列表中
解法1:用 insert 方法
>>> num = [1, 2, 4, 5]
>>> num.insert(2, 'three')
>>> num
[1, 2, 'three', 4, 5]
解法2:用切片的方式插入
>>> num = [1, 2, 4, 5]
>>> num[2:2] = ['three']
>>> num
[1, 2, 'three', 4, 5]
怎么删除列表中元素
pop 方法可以删除指定元素,不指定位置的话默认删除最后一个元素
>>> num = [1, 2, 4, 5]
>>> num.pop()
5
>>> num
[1, 2, 4]
>>> num.pop(1)
2
>>> num
[1, 4]
怎么删除列表中指定元素
用 remove 方法
>>> num
[1, 4]
>>> num = [1, 2, 4, 5, 4]
>>> num.remove(4)
>>> num
[1, 2, 5, 4]
remove 方法只会删除第一次出现的元素
怎么让列表按相反顺序排列?
解法1:用 reverse 方法
>>> num = [1, 22, 45, 99, 49]
>>> num.reverse()
>>> num
[49, 99, 45, 22, 1]
解法2:用切片的方式
>>> num = [1, 22, 45, 99, 49]
>>> num[::-1]
[49, 99, 45, 22, 1]
怎么表示只包含一个元素的元组
1个元素的元组,必须在唯一的元素后加上逗号,否则不是元组
>>> t= (1)
>>> type(t)
<class 'int'>
>>> t= (1,)
>>> type(t)
<class 'tuple'>
怎么批量替换字符串中的元素
用 replace 方法
>>> 'i love Python'.replace('o', 'ee')
'i leeve Pytheen'
怎么把字符串按照空格进行拆分
用 split 方法,括号为空的情况下默认以空格拆分
>>> 'i love Python'.split()
['i', 'love', 'Python']
怎么去除字符串首位的空格
用 strip 方法
>>> ' i love Python '.strip()
'i love Python'
怎么给字典中不存在的key指定默认值
>>> d = {'age': 42, 'name': 'g'}
>>> d.get('aa', 'N/A')
'N/A'
怎么快速求 1 到 100 所有整数相加之和
>>> sum(range(1, 101))
5050
怎么查出模块包含哪些属性?
用 dir 方法
>>> dir(requests)
['ConnectTimeout', 'ConnectionError', 'DependencyWarning', 'FileModeWarning', 'HTTPError', 'NullHandler', 'PreparedRequest', 'ReadTimeout', 'Request', 'RequestException', 'RequestsDependencyWarning', 'Response', 'Session', 'Timeout', 'TooManyRedirects', 'URLRequired', '__author__', '__author_email__', '__build__', '__builtins__', '__cached__', '__cake__', '__copyright__', '__description__', '__doc__', '__file__', '__license__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__title__', '__url__', '__version__', '_check_cryptography', '_internal_utils', 'adapters', 'api', 'auth', 'certs', 'chardet', 'check_compatibility', 'codes', 'compat', 'cookies', 'delete', 'exceptions', 'get', 'head', 'hooks', 'logging', 'models', 'options', 'packages', 'patch', 'post', 'put', 'request', 'session', 'sessions', 'status_codes', 'structures', 'urllib3', 'utils', 'warnings']
怎么快速查看某个模块的帮助文档
>>> range.__doc__
'range(stop) -> range object
range(start, stop[, step]) -> range object
Return an object that produces a sequence of integers from start (inclusive)
to stop (exclusive) by step. range(i, j) produces i, i+1, i+2, ..., j-1.
start defaults to 0, and stop is omitted! range(4) produces 0, 1, 2, 3.
These are exactly the valid indices for a list of 4 elements.
When step is given, it specifies the increment (or decrement).
Process finished with exit code 0
'
怎么快速启动浏览器打开指定网站
使用 webbrowser 库
import webbrowser
webbrowser.open('http://www.python.org')
Python里占位符怎么表示?
用 pass 占位,当你还没想好代码块的逻辑时,你需要运行代码调试其他功能,需要加占位符,不然会报错
if name == '小明':
print('听我的')
elif name == '小花':
pass
怎么给函数编写文档?
在 def 语句后面把注释文档放在引号(单引、双引、三引都可以)里面就行,这个文档可以通过 function.__doc__访问。
>>> def square(x):
"""返回平方值"""
return x*x
>>> square.__doc__
'返回平方值'
怎么定义私有方法?
在方式名称前加两个下斜杠 __
>>> class Person:
def __name(self):
print('私有方法')
用 from module import * 导入时不会导入私有方法。
怎么判断一个类是否是另一个类的子类?
用 issubclass 方法,2 个参数,如果第一个参数是第二个参数的子类,返回 True,否则返回 False
>>> class A:
pass
>>> class B(A):
pass
>>> issubclass(B, A)
True
怎么从一个非空序列中随机选择一个元素?
用 random 中的 choice 方法
>>> import random
>>> random.choice([1, 'two', 3, '肆'])
3
怎么查出通过 from xx import xx导入的可以直接调用的方法?
用 all 方法,这个方法查出的是模块下不带_的所有方法,可以直接调用。
>>> import random
>>> random.__all__
['Random', 'seed', 'random', 'uniform', 'randint', 'choice', 'sample', 'randrange', 'shuffle', 'normalvariate', 'lognormvariate', 'expovariate', 'vonmisesvariate', 'gammavariate', 'triangular', 'gauss', 'betavariate', 'paretovariate', 'weibullvariate', 'getstate', 'setstate', 'getrandbits', 'choices', 'SystemRandom']
花括号{} 是集合还是字典?
字典
>>> type({})
<class 'dict'>
怎么求两个集合的并集?
解法1:用 union 方法
>>> a = {6, 7, 8}
>>> b = {7, 8, 9}
>>> a.union(b)
{6, 7, 8, 9}
解法2:使用按位或运算符 |
>>> a = {6, 7, 8}
>>> b = {7, 8, 9}
>>> a | b
{6, 7, 8, 9}
求两个集合的交集
解法1:
>>> a = {6, 7, 8}
>>> b = {7, 8, 9}
>>> a&b
{8, 7}
解法2:用 intersection 方法
>>> a = {6, 7, 8}
>>> b = {7, 8, 9}
>>> a.intersection(b)
{8, 7}
求两个集合中不重复的元素?
差集指的是两个集合交集外的部分
解法1: 使用运算符 ^
>>> a = {6, 7, 8}
>>> b = {7, 8, 9}
>>> a ^ b
{9, 6}
解法2:使用 symmetric_difference 方法
>>> a = {6, 7, 8}
>>> b = {7, 8, 9}
>>> a.symmetric_difference(b)
{9, 6}
求两个集合的差集?
解法1:用运算符 -
>>> a = {6, 7, 8}
>>> b = {7, 8, 9}
>>> a-b
{6}
解法2:用 difference 方法
>>> a = {6, 7, 8}
>>> b = {7, 8, 9}
>>> a.difference(b)
{6}
从一个序列中随机返回 n 个不同值的元素
用 random 中的 sample 方法
>>> import random
>>> t = (2020, 7, 3, 21, 48, 56, 4, 21, 0)
>>> random.sample(t, 2)
[56, 0]
怎么生成两个数之间的随机实数
用 random 中的 uniform 方法
>>> random.uniform(10, 20)
11.717127223103947
怎么在等差数列中随机选择一个数
用 random 中的 randrange 方法
>>> random.randrange(0, 100, 10)
70
怎么在文件里写入字符?
用 open 函数,模式用 w
>>> with open('bruce.txt', 'w') as f:
f.write('hello world')
11
怎么读取文件内容?
用 open 函数,模式用 r(默认情况下是r)
>>> with open('bruce.txt', 'r') as f:
f.read()
'hello world'
怎么把程序打包成 exe 文件
用 Setuptools 里的 py2exe 库
怎么把程序打包成 Mac 系统可运行的 .app 文件
-
安装py2app
pip3 install py2app
-
cd 到Demo.py文件所在的目录
-
py2applet --make-setup Demo.py 完成显示生成setup.py
怎么获取路径下所有目录名称?
用 sys 下的 path 方法,返回的是目录名称的字符串列表
>>> sys.path
['', '/Users/brucepk/Documents', '/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python37.zip', '/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7', '/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload', '/usr/local/lib/python3.7/site-packages']
Python 环境下怎么执行操作系统命令?
用 os 模块下的 system 方法
>>> os.system('cd /Users/brucepk/Desktop && mkdir aaa.txt')
256
怎么将当前时间转为字符串?
用 time 模块里的 asctime 方法
>>> import time
>>> time.asctime()
'Sat Jul 4 17:36:00 2020'
怎么将秒数转为时间数组
用 time 模块里的 localtime 方法
>>> import time
>>> time.localtime(1888888888)
time.struct_time(tm_year=2029, tm_mon=11, tm_mday=9, tm_hour=11, tm_min=21, tm_sec=28, tm_wday=4, tm_yday=313, tm_isdst=0)
将时间元组转换为从新纪元后的秒数
用 time 模块里的 mktime 方法
>>> time.mktime((2020, 7, 3, 21, 48, 56, 4, 21, 0))
1593784136.0
怎么将字符串转为时间元组
用 time 模块里的 strptime 方法
>>> import time
>>> time.strptime('Sun Jul 5 08:29:51 2020')
time.struct_time(tm_year=2020, tm_mon=7, tm_mday=5, tm_hour=8, tm_min=29, tm_sec=51, tm_wday=6, tm_yday=187, tm_isdst=-1)
怎么随机打乱列表的顺序
用 random 模块里的 shuffle 方法
>>> import random
>>> t = list(range(20))
>>> t
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> random.shuffle(t)
>>> t
[16, 3, 13, 7, 6, 12, 17, 4, 15, 2, 5, 8, 18, 10, 9, 19, 14, 0, 1, 11]
Python进阶习题
怎么用for循环实现把字符串变成Unicode码位的列表
>>> st = '!@#$%^&*'
>>> codes = []
>>> for s in st:
codes.append(ord(s))
>>> codes
[33, 64, 35, 36, 37, 94, 38, 42]
怎么用列表推导式实现把字符串变成Unicode码位的列表
>>> st = '!@#$%^&*'
>>> codes = [ord(s) for s in st]
>>> codes
[33, 64, 35, 36, 37, 94, 38, 42]
很明显,用列表推导式实现比 for 循环加 append 更高效简洁,可读性更好。
打印出两个列表的笛卡尔积
解法1:使用生成器表达式产生笛卡尔积,可以帮忙省掉运行 for 循环的开销。
>>> colors = ['blacks', 'white']
>>> sizes = ['S', 'M', 'L']
>>> for tshirt in ('%s %s'%(c, s) for c in colors for s in sizes):
print(tshirt)
blacks S
blacks M
blacks L
white S
white M
white L
解法2:使用 itertools 里的 product 生成器函数。
>>> import itertools
>>> list(itertools.product(['blacks', 'white'], ['S', 'M', 'L']))
[('blacks', 'S'), ('blacks', 'M'), ('blacks', 'L'), ('white', 'S'), ('white', 'M'), ('white', 'L')]
可迭代对象拆包时,怎么赋值给占位符
我们经常用 for 循环提取元组里的元素,对于我们不想接收的元素,我们可以用占位符 _ 接收。
>>> player_infos = [('Kobe', '24'), ('James', '23'), ('Iverson', '3')]
>>> for player_names, _ in player_infos:
print(player_names)
Kobe
James
Iverson
Python3 中,用什么方式接收不确定值或参数
用 *args 的方式,*args 位置可以在任意位置。
>>> a, b, *c = range(8)
>>> a, b, c
(0, 1, [2, 3, 4, 5, 6, 7])
>>> a, *b, c, d = range(5)
>>> a,b,c,d
(0, [1, 2], 3, 4)
>>> *a, b, c, d = range(5)
>>> a,b,c,d
([0, 1], 2, 3, 4)
用切片将对象倒序
>>> s = 'basketball'
>>> s[::-1]
'llabteksab'
怎么查看列表的 ID
>>> l = [1, 2, 3]
>>> id(l)
4507638664
可变序列用*=(就地乘法)后,会创建新的序列吗?
不会,可变序列用*=(就地乘法)后,不会创建新的序列,新元素追加到老元素上,以列表为例,我们看下新老列表的id,相等的。
>>> l = [1, 2, 3]
>>> id(l)
4507939272
>>> l *= 2
>>> l
[1, 2, 3, 1, 2, 3]
>>> id(l)
4507939272
不可变序列用*=(就地乘法)后,会创建新的序列吗?
会,不可变序列用*=(就地乘法)后,会创建新的序列,以元组为例,我们看下新老元组的id,是不同的。
>>> t = (1, 2, 3)
>>> id(t)
4507902240
>>> t *= 2
>>> t
(1, 2, 3, 1, 2, 3)
>>> id(t)
4507632648
所以,对不可变序列进行重复拼接操作的话,效率会很低,因为每次都有一个新对象,而解释器需要把原来对象中的元素先复制到新的对象里,然后再追加新的元素。
关于+=的一道谜题
t = (1, 2, [30, 40])
t[2] += [50, 60]
到底会发生下面4种情况中的哪一种?
a. t变成(1, 2, [30, 40, 50, 60])。
b.因为tuple不支持对它的元素赋值,所以会抛出TypeError异常。
c.以上两个都不是。
d. a和b都是对的。
答案是d,请看下运行结果。
>>> t = (1, 2, [30, 40])
>>> t[2] += [50, 60]
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
t[2] += [50, 60]
TypeError: 'tuple' object does not support item assignment
>>> t
(1, 2, [30, 40, 50, 60])
sort() 和 sorted() 区别
l = [1, 9, 5, 8]
j = l.sort()
k = sorted(l)
通过 Python Tutor 工具我们可以看到,sort() 会就地在原序列上排序,sorted() 新建了一个新的序列。
list.sort方法会就地排序列表,也就是说不会把原列表复制一份。这也是这个方法的返回值是None的原因,提醒你本方法不会新建一个列表。在这种情况下返回None其实是Python的一个惯例:如果一个函数或者方法对对象进行的是就地改动,那它就应该返回None,好让调用者知道传入的参数发生了变动,而且并未产生新的对象。
怎么通过 reverse 参数对序列进行降序排列
reverse 参数一般放在 sorted() 方法里面,reverse 默认值为 False,序列默认升序排列,降序排列的话需要将 reverse 值设置为 True。
>>> l = [1, 9, 5, 8]
>>> j = sorted(l, reverse=True)
>>> j
[9, 8, 5, 1]
numpy 怎么把一维数组变成二维数组
>>> a = numpy.arange(12)
>>> a
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
>>> a.shape = 3, 4
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
快速插入元素到列表头部
可以通过切片指定位置插入,头部就是[0:0]
>>> l = [1, 2, 3, 4, 5]
>>> l[0:0] = 'Python'
>>> l
['P', 'y', 't', 'h', 'o', 'n', 1, 2, 3, 4, 5]
还可以通过 insert() 方法插入,第一个参数是位置的坐标,从 0 开始。
>>> l = [1, 2, 3, 4, 5]
>>> l.insert(0, 'first')
>>> l
['first', 1, 2, 3, 4, 5]
在第一个元素之前添加一个元素之类的操作是很耗时的,因为这些操作会牵扯到移动列表里的所有元素。有没有更高效的方法?用双向队列 deque 类。
deque 类可以指定这个队列的大小,如果这个队列满员了,还可以从反向端删除过期的元素,然后在尾端添加新的元素。
>>> from collections import deque
>>> dp = deque(range(10), maxlen=15)
>>> dp
deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=15)
>>> dp.appendleft(-1)
>>> dp
deque([-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=15)
字典的创建方法
Python中,你知道怎么创建字典吗?
a = dict(one=1, two=2, three=3)
b = {'one': 1, 'two': 2, 'three': 3}
c = dict(zip(['one', 'two', 'three'], [1, 2, 3]))
d = dict([('two', 2), ('one', 1), ('three', 3)])
e = dict({'one': 1, 'two': 2, 'three': 3})
用字典推导(dictcomp)构建字典
dial_code = [
(86, 'China'),
(91, 'India'),
(1, 'US'),
(55, 'Brazil'),
(7, 'Russia'),
(81, 'Japan')
]
coutry_code = {coutry:code for code, coutry in dial_code}
通过一次查询给字典里不存的键赋予新值
用setdefault方法,只查询一次,效果更快
coutry_code = {'China': 86, 'India': 91, 'US': 1, 'Brazil': 55, 'Russia': 7, 'Japan': 81}
coutry_code.setdefault('china', []).append(86)
如果用下面这种方法,需要查询三次
if 'china' not in coutry_code:
coutry_code['china'] = []
coutry_code['china'].append(86)
print(coutry_code)
像k in my_dict.keys( )这种操作在Python 3中是很快的,而且即便映射类型对象很庞大也没关系。这是因为dict.keys( )的返回值是一个“视图”。视图就像一个集合,而且跟字典类似的是,在视图里查找一个元素的速度很快。在“Dictionary view objects”里可以找到关于这个细节的文档。Python 2的dict.keys( )返回的是个列表,因此虽然上面的方法仍然是正确的,它在处理体积大的对象的时候效率不会太高,因为k in my_list操作需要扫描整个列表。
怎么统计字符串中元素出现的个数?
用collections中的Counter方法统计,返回的结果是对应元素和个数形成的键值对。
ct = collections.Counter('adcfadcfgbsdcv')
结果:
Counter({'d': 3, 'c': 3, 'a': 2, 'f': 2, 'g': 1, 'b': 1, 's': 1, 'v': 1})
怎么统计出排名前n的元素?
用most_common方法,参数里填n,比如前两名的话
ct.most_common(2)
结果
[('d', 3), ('c', 3)]
列表去重
>>> l = ['A', 'B', 'A', 'B']
>>> list(set(l))
['A', 'B']
求m中元素在n中出现的次数
基础解法:
>>> m = {'A', 'B', 'C'}
>>> n = {'B', 'C', 'D'}
>>> found = 0
>>> for i in m:
if i in n:
found += 1
>>> found
2
高级解法:
>>> m = {'A', 'B', 'C'}
>>> n = {'B', 'C', 'D'}
>>> len(m & n)
2
如果m和n不是集合的话,直接转换后再取交集
>>> m = {'A', 'B', 'C'}
>>> n = {'B', 'C', 'D'}
>>> len(set(m) & srt(n))
2
高级解法的另一种写法:
>>> m = {'A', 'B', 'C'}
>>> n = {'B', 'C', 'D'}
>>> len(set(m).intersection(n))
2
新建一个Latin-1字符集合,该集合里的每个字符的Unicode名字里都有“SIGN”这个单词,用集合推导式完成。
>>> from unicodedata import name
>>> {chr(i) for i in range(32, 256) if 'SIGN' in name(chr(i), '')}
{'§', '%', '#', '+', '¬', '£', '<', '$', '=', 'µ', '®', '÷', '©', '±', '°', '¤', '¥', '¶', '×', '>', '¢'}
查询系统默认编码方式
>>> fp = open('test.txt', 'w')
>>> fp.encoding
'cp936'
修改编码方式
>>> fp = open('test.txt', 'w', encoding='utf-8')
>>> fp.encoding
'utf-8'
用递归实现阶乘
def factorial(n):
""":return n!"""
return 1 if n < 2 else n * factorial(n-1)
>>> all([])的输出结果是多少?
True
>>> any([])的输出结果是多少?
False
怎么判断对象是否可被调用?
用 Python 内置的函数 callable() 判断
>>> [callable(obj) for obj in (abs, str, 2)]
[True, True, False]
怎么列出对象的所有属性
使用 dir 函数来获取对象的所有属性。
>>> import requests
>>> dir(requests)
['ConnectTimeout', 'ConnectionError', 'DependencyWarning', 'FileModeWarning', 'HTTPError', 'NullHandler', 'PreparedRequest', 'ReadTimeout', 'Request', 'RequestException', 'RequestsDependencyWarning', 'Response', 'Session', 'Timeout', 'TooManyRedirects', 'URLRequired', '__author__', '__author_email__', '__build__', '__builtins__', '__cached__', '__cake__', '__copyright__', '__description__', '__doc__', '__file__', '__license__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__title__', '__url__', '__version__', '_check_cryptography', '_internal_utils', 'adapters', 'api', 'auth', 'certs', 'chardet', 'check_compatibility', 'codes', 'compat', 'cookies', 'cryptography_version', 'delete', 'exceptions', 'get', 'head', 'hooks', 'logging', 'models', 'options', 'packages', 'patch', 'post', 'put', 'pyopenssl', 'request', 'session', 'sessions', 'status_codes', 'structures', 'urllib3', 'utils', 'warnings']
怎么得到类的实例没有而函数有的属性列表
创建一个空的用户定义的类和空的函数,计算差集,然后排序。
>>> class C:
pass
>>> obj = C()
>>> def func():
pass
>>> sorted(set(dir(func)) - set(dir(obj)))
['__annotations__', '__call__', '__closure__', '__code__', '__defaults__', '__get__', '__globals__', '__kwdefaults__', '__name__', '__qualname__']
函数中,不想支持数量不定的定位参数,但是想支持仅限关键字参数,参数怎么定义
那就要在关键字参数前加一个 *。
>>> def f(a, *, b):
return a, b
>>> f(1, b=2)
(1, 2)
这样的话,b 参数强制必须传入实参,否则会报错。
怎么给函数参数和返回值注解
代码执行时,注解不会做任何处理,只是存储在函数的__annotations__属性(一个字典)中。
def function(text: str, max_len: 'int > 0' = 80) -> str:
函数声明中的各个参数可以在:之后增加注解表达式。如果参数有默认值,注解放在参数名和=号之间。如果想注解返回值,在)和函数声明末尾的:之间添加->和一个表达式。
Python对注解所做的唯一的事情是,把它们存储在函数的__annotations__属性里。仅此而已,Python不做检查、不做强制、不做验证,什么操作都不做。换句话说,注解对Python解释器没有任何意义。注解只是元数据,可以供IDE、框架和装饰器等工具使用
不使用递归,怎么高效写出阶乘表达式
通过 reduce 和 operator.mul 函数计算阶乘
>>> from functools import reduce
>>> from operator import mul
>>> def fact(n):
return reduce(mul, range(1, n+1))
>>> fact(5)
120
Python什么时候执行装饰器?
函数装饰器在导入模块时立即执行,而被装饰的函数只在明确调用时运行。这突出了Python程序员所说的导入时和运行时之间的区别。
判断下面语句执行是否会报错?
>>> b = 3
>>> def fun(a):
print(a)
print(b)
b = 7
>>> fun(2)
会报错,Python编译函数的定义体时,先做了一个判断,那就是 b 是局部变量,因为在函数中给它赋值了。但是执行 print(b) 时,往上又找不到 b 的局部值,所以会报错。
Python 设计如此,Python 不要求声明变量,但是假定在函数定义体中赋值的变量是局部变量。
2
Traceback (most recent call last):
File "<pyshell#50>", line 1, in <module>
fun(2)
File "<pyshell#49>", line 3, in fun
print(b)
UnboundLocalError: local variable 'b' referenced before assignment
怎么强制把函数中局部变量变成全局变量
用 global 声明
>>> b = 3
>>> def fun(a):
global b
print(a)
print(b)
b = 7
>>> b = 5
>>> fun(2)
2
5
闭包中,怎么对数字、字符串、元组等不可变元素更新
我们知道,在闭包中,声明的变量是局部变量,局部变量改变的话会报错。
>>> def make_averager():
count = 0
total = 0
def averager (new_value):
count += 1
total += new_value
return total / count
return averager
>>> avg = make_averager()
>>> avg(10)
Traceback (most recent call last):
File "<pyshell#63>", line 1, in <module>
avg(10)
File "<pyshell#61>", line 5, in averager
count += 1
UnboundLocalError: local variable 'count' referenced before assignment
为了解决这个问题,Python 3引入了 nonlocal 声明。它的作用是把变量标记为自由变量
>>> def make_averager():
count = 0
total = 0
def averager (new_value):
nonlocal count, total
count += 1
total += new_value
return total / count
return averager
>>> avg = make_averager()
>>> avg(10)
10.0
Python2 怎么解决访问外部变量报错的问题
https://www.python.org/dev/peps/pep-3104/
测试代码运行的时间
用 time 模块里的 perf_counter 方法。
>>> t0 = time.perf_counter()
>>> for i in range(10000):
pass
>>> t1 = time.perf_counter()
>>> t1-t0
或者,直接用 time.time()
>>> import time
>>> t0 = time.time()
>>> for i in range(10000):
pass
>>> t1 = time.time()
>>> t1-t0
怎么优化递归算法,减少执行时间
使用装饰器 functools.lru_cache() 缓存数据
>>> import functools
>>> @functools.lru_cache()
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-2)+fibonacci(n-1)
>>> fibonacci(6)
8
标准库singledispatch官方文档:https://www.python.org/dev/peps/pep-0443/
比较两个对象的值(对象中保存的数据)是否相等
用 == 运算符比较
>>> a = [1, 2, 3]
>>> b = [1, 2, 3]
>>> a==b
True
比较两个对象的内存地址 id 是否相等
用 is 比较,ID一定是唯一的数值标注,而且在对象的生命周期中绝不会变
>>> a = [1, 2, 3]
>>> b = [1, 2, 3]
>>> a is b
False
怎么格式化显示对象?
可以用内置的 format( )函数和str.format( )方法。
format(my_obj, format_spec)的第二个参数,或者str.format( )方法的格式字符串,{}里代换字段中冒号后面的部分。
>>> from datetime import datetime
>>> now = datetime.now()
>>> format(now, '%H:%M:%S')
'08:18:21'
>>> "It's now {:%I:%M%p}".format(now)
"It's now 08:18AM"
复制一个序列并去掉后 n 个元素
可能有同学会想到用 pop(),但这个方法会就地删除原序列,不会复制出一个新的序列。
可以用切片的思想,比如复制后去掉后两个元素。
>>> l = [1, 2, 3, 4, 5]
>>> j = l[:-2]
>>> j
[1, 2, 3]
Python中怎么定义私有属性。
在属性前加两个前导下划线,尾部没有或最多有一个下划线
怎么随机打乱一个列表里元素的顺序
用 random 里的 shuffle 方法
>>> from random import shuffle
>>> l = list(range(30))
>>> shuffle(l)
>>> l
[28, 15, 3, 25, 16, 18, 23, 10, 11, 21, 12, 7, 4, 0, 24, 6, 5, 22, 8, 13, 29, 9, 27, 17, 2, 20, 1, 26, 19, 14]
>>>
怎么判断某个对象或函数是一个已知的类型
用 Python 的内置函数 isinstance() 判读
>>> isinstance('aa', str)
True
怎么打印出分数
用 fractions 中的 Fraction 方法
>>> from fractions import Fraction
>>> print(Fraction(1, 3))
1/3
+ 和 += 区别
-
两边必须是同类型的对象才能相加,+= 右操作数往往可以是任何可迭代对象。
>>> l = list(range(6))
>>> l += 'qwer'
>>> l
[0, 1, 2, 3, 4, 5, 'q', 'w', 'e', 'r']
>>> j = l + (6, 7)
Traceback (most recent call last):
File "<pyshell#91>", line 1, in <module>
j = l + (6, 7)
TypeError: can only concatenate list (not "tuple") to list
怎么列出一个目录下所有的文件名和子文件名
用 os.walk 生成器函数,我用 site-packages 目录举例。
>>> import os
>>> dirs = os.walk('C:\Program Files\Python36\Lib\site-packages')
>>> for dir in dirs:
print(dir)
('C:\\Program Files\\Python36\\Lib\\site-packages', ['ad3', 'ad3-2.2.1.dist-info', 'adodbapi', 'aip', 'appium', 'AppiumLibrary', 'Appium_Python_Client-0.46-py3.6.egg-info', 'apscheduler', 'APScheduler-3.6.0.dist-info', 'atomicwrites', 'atomicwrites-1.3.0.dist-info', ...)
怎么返回 1 到 10 的阶乘列表
高效的方法需要用到 itertools 和 operator 模块,导包后一行代码搞定。
>>> import itertools
>>> import operator
>>> list(itertools.accumulate(range(1, 11), operator.mul))
[1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]
怎么快速拼接字符串和序列形成新的列表
用 itertools 里的 chain 方法可以一行代码搞定。
>>> import itertools
>>> list(itertools.chain('ABC', range(5)))
['A', 'B', 'C', 0, 1, 2, 3, 4]
进度条显示
用 tqdm 库
>>> import time
>>> from tqdm import tqdm
>>> for i in tqdm(range(1000)):
time.sleep(.01)
0%| | 0/1000 [00:00<?, ?it/s]
1%| | 9/1000 [00:00<00:11, 88.38it/s]
2%|1 | 15/1000 [00:00<00:13, 74.85it/s]
2%|1 | 19/1000 [00:00<00:17, 56.93it/s]
2%|2 | 25/1000 [00:00<00:17, 56.70it/s]
3%|3 | 30/1000 [00:00<00:19, 50.90it/s
一个学习Python的人,喜欢分享,喜欢搞事情!
长按下图二维码关注,和你一起领悟Python的魅力。
Python知识圈公众号的交流群已经建立,群里可以领取 Python 和人工智能学习资料,大家可以一起学习交流,效率更高,如果是想发推文、广告、砍价小程序的敬请绕道!一定记得备注「交流学习」,我会尽快通过好友申请哦!通过好友后私聊我「学习资料」或者「进群」都可以。
扫码添加,备注:交流学习
本文分享自微信公众号 - 早起Python(zaoqi-python)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
来源:oschina
链接:https://my.oschina.net/u/4579171/blog/4591887