国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

Python程序員鮮為人知但你應(yīng)該知道的17個問題

2019-11-25 18:24:12
字體:
供稿:網(wǎng)友

一、不要使用可變對象作為函數(shù)默認(rèn)值

復(fù)制代碼 代碼如下:
In [1]: def append_to_list(value, def_list=[]):
   ...:         def_list.append(value)
   ...:         return def_list
   ...:

In [2]: my_list = append_to_list(1)

In [3]: my_list
Out[3]: [1]

In [4]: my_other_list = append_to_list(2)

In [5]: my_other_list
Out[5]: [1, 2] # 看到了吧,其實我們本來只想生成[2] 但是卻把第一次運行的效果頁帶了進來

In [6]: import time

In [7]: def report_arg(my_default=time.time()):
   ...:         print(my_default)
   ...:

In [8]: report_arg() # 第一次執(zhí)行
1399562371.32

In [9]: time.sleep(2) # 隔了2秒

In [10]: report_arg()
1399562371.32 # 時間竟然沒有變


這2個例子說明了什么? 字典,集合,列表等等對象是不適合作為函數(shù)默認(rèn)值的. 因為這個默認(rèn)值實在函數(shù)建立的時候就生成了, 每次調(diào)用都是用了這個對象的”緩存”. 我在上段時間的分享python高級編程也說到了這個問題,這個是實際開發(fā)遇到的問題,好好檢查你學(xué)過的代碼, 也許只是問題沒有暴露

可以這樣改:

復(fù)制代碼 代碼如下:

def append_to_list(element, to=None):
    if to is None:
        to = []
    to.append(element)
    return to

二、生成器不保留迭代過后的結(jié)果

復(fù)制代碼 代碼如下:
In [12]: gen = (i for i in range(5))

In [13]: 2 in gen
Out[13]: True

In [14]: 3 in gen
Out[14]: True

In [15]: 1 in gen
Out[15]: False # 1為什么不在gen里面了? 因為調(diào)用1->2,這個時候1已經(jīng)不在迭代器里面了,被按需生成過了

In [20]: gen = (i for i in range(5))

In [21]: a_list = list(gen) # 可以轉(zhuǎn)化成列表,當(dāng)然a_tuple = tuple(gen) 也可以

In [22]: 2 in a_list
Out[22]: True

In [23]: 3 in a_list
Out[23]: True

In [24]: 1 in a_list # 就算循環(huán)過,值還在
Out[24]: True

三、lambda在閉包中會保存局部變量

復(fù)制代碼 代碼如下:

In [29]: my_list = [lambda: i for i in range(5)]

In [30]: for l in my_list:
   ....:         print(l())
   ....:
4
4
4
4
4


這個問題還是上面說的python高級編程中說過具體原因. 其實就是當(dāng)我賦值給my_list的時候,lambda表達式就執(zhí)行了i會循環(huán),直到 i =4,i會保留

但是可以用生成器

復(fù)制代碼 代碼如下:

In [31]: my_gen = (lambda: n for n in range(5))

In [32]: for l in my_gen:
   ....:         print(l())
   ....:
0
1
2
3
4


也可以堅持用list:
復(fù)制代碼 代碼如下:

In [33]: my_list = [lambda x=i: x for i in range(5)] # 看我給每個lambda表達式賦了默認(rèn)值

In [34]: for l in my_list:
   ....:         print(l())
   ....:
0
1
2
3
4


有點不好懂是吧,在看看python的另外一個魔法:
復(fù)制代碼 代碼如下:

In [35]: def groupby(items, size):
   ....:     return zip(*[iter(items)]*size)
   ....:

In [36]: groupby(range(9), 3)
Out[36]: [(0, 1, 2), (3, 4, 5), (6, 7, 8)]


一個分組的函數(shù),看起來很不好懂,對吧? 我們來解析下這里
復(fù)制代碼 代碼如下:

In [39]: [iter(items)]*3
Out[39]:
[<listiterator at 0x10e155fd0>,
 <listiterator at 0x10e155fd0>,
 <listiterator at 0x10e155fd0>] # 看到了吧, 其實就是把items變成可迭代的, 重復(fù)三回(同一個對象哦), 但是別忘了,每次都.next(), 所以起到了分組的作用
 In [40]: [lambda x=i: x for i in range(5)]
Out[40]:
[<function __main__.<lambda>>,
 <function __main__.<lambda>>,
 <function __main__.<lambda>>,
 <function __main__.<lambda>>,
 <function __main__.<lambda>>] # 看懂了嗎?


四、在循環(huán)中修改列表項

復(fù)制代碼 代碼如下:
In [44]: a = [1, 2, 3, 4, 5]

In [45]: for i in a:
   ....:     if not i % 2:
   ....:         a.remove(i)
   ....:

In [46]: a
Out[46]: [1, 3, 5] # 沒有問題

In [50]: b = [2, 4, 5, 6]

In [51]: for i in b:
   ....:      if not i % 2:
   ....:          b.remove(i)
   ....:

In [52]: b
Out[52]: [4, 5] # 本來我想要的結(jié)果應(yīng)該是去除偶數(shù)的列表


思考一下,為什么 主站蜘蛛池模板: 盖州市| 达州市| 马龙县| 丽江市| 汉源县| 油尖旺区| 仲巴县| 肥西县| 连平县| 新泰市| 盐亭县| 康平县| 普兰店市| 布拖县| 黔西县| 闵行区| 厦门市| 师宗县| 平陆县| 如皋市| 改则县| 龙井市| 鸡泽县| 重庆市| 论坛| 廉江市| 唐海县| 常熟市| 中超| 安平县| 达日县| 河北省| 玉龙| 定边县| 汨罗市| 长春市| 拜泉县| 哈尔滨市| 五常市| 闸北区| 清河县|