1.怎么計算2的3次方
解法1:直接用運算符 **
>>> 2**3
8
解法2:用函數 pow
>>> pow(2,3)
8
2.怎么找出序列中的最大最小值?
用內置函數 max 和 min
>>> l = (123, 888, 666)
>>> max(l)
888
>>> min(l)
123
3.怎么將字符列表轉為字符串
用 join 方法,合並序列的元素
>>> l = ['Python', 'Circle', 'is', 'ok']
>>> j = ' '.join(l)
>>> j
'Python Circle is ok'
4.怎么快速打印出包含所有 ASCII 字母(大寫和小寫)的字符串
用 string 模塊的方法
>>> import string
>>> string.ascii_letters
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
5.怎么讓字符串居中
用字符串中的 center 方法,他會在兩邊自動填充字符(默認為空格),讓字符串居中
>>> k = '更多精彩,請關注公眾號「Python知識圈」'
>>> k.center(50)
' 更多精彩,請關注公眾號「Python知識圈」 '
>>> k.center(50, '*')
'**************更多精彩,請關注公眾號「Python知識圈」**************'
6.怎么在字符串中找到子串
用 find 方法,如果找到,就返回子串的第一個字符的索引,否則返回 -1
>>> ss = 'I Love Python'
>>> ss.find('I')
0
>>> ss.find('Python')
7
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'
8.怎么清空列表內容
解法1:用 clear 方法
>>> l = [1, 2, 3]
>>> l.clear()
>>> l
[]
解法2:用切片賦值的方法
>>> k = [1, 2, 3]
>>> k[:] = []
>>> k
[]
9.怎么計算指定的元素在列表中出現了多少次?
用 count 方法
>>> l = ['i', 'am', 'ok', 'ok']
>>> l.count('ok')
2
10.怎么在列表末尾加入其它元素
用 extend 方法
>>> l = [1, 2, 3]
>>> j = [4, 5, 6]
>>> l.extend(j)
>>> l
[1, 2, 3, 4, 5, 6]
11.extend 和列表相加的區別?
兩者看起來效果一致
>>> l = [1, 2, 3]
>>> j = [4, 5, 6]
>>> l + j
[1, 2, 3, 4, 5, 6]
extend 是直接在 l 列表里加入元素,相加會生成一個新元素,並不會對 l 做修改。
12.怎么查找列表中某個元素第一次出現的索引,從 0 開始
用 index 方法
>>> l = ['are', 'you', 'ok']
>>> l.index('you')
1
13.怎么將一個對象插入到列表中
解法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]
14.怎么刪除列表中元素
pop 方法可以刪除指定元素,不指定位置的話默認刪除最后一個元素
>>> num = [1, 2, 4, 5]
>>> num.pop()
5
>>> num
[1, 2, 4]
>>> num.pop(1)
2
>>> num
[1, 4]
15.怎么刪除列表中指定元素
用 remove 方法
>>> num
[1, 4]
>>> num = [1, 2, 4, 5, 4]
>>> num.remove(4)
>>> num
[1, 2, 5, 4]
remove 方法只會刪除第一次出現的元素
16.怎么讓列表按相反順序排列?
解法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]
17.怎么表示只包含一個元素的元組
1個元素的元組,必須在唯一的元素后加上逗號,否則不是元組
>>> t= (1)
>>> type(t)
<class 'int'>
>>> t= (1,)
>>> type(t)
<class 'tuple'>
18.怎么批量替換字符串中的元素
用 replace 方法
>>> 'i love Python'.replace('o', 'ee')
'i leeve Pytheen'
19.怎么把字符串按照空格進行拆分
用 split 方法,括號為空的情況下默認以空格拆分
>>> 'i love Python'.split()
['i', 'love', 'Python']
20.怎么去除字符串首位的空格
用 strip 方法
>>> ' i love Python '.strip()
'i love Python'
21.怎么給字典中不存在的key指定默認值
>>> d = {'age': 42, 'name': 'g'}
>>> d.get('aa', 'N/A')
'N/A'
22.怎么快速求 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