python开发中遇到的难题_初学者在Python开发中常见的问题
(上)
前⾔:这篇⽂章主要介绍了Python程序员代码编写时应该避免的17个“坑”,也是Python程序员代码编写时应该避免的17个问题,如果有知友想要了解Python,⽂末有⿊马程序员的Python免费教程,需要的知友可以参考⼀下~如果喜欢请点赞哈
⼀、不要使⽤可变对象作为函数默认值
[url=]复制代码[/url]代码如下:
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() # 第⼀次执⾏
1399562371.32
In [9]: time.sleep(2) # 隔了2秒
In [10]: report_arg()
1399562371.32 # 时间竟然没有变
这2个例⼦说明了什么? 字典,集合,列表等等对象是不适合作为函数默认值的. 因为这个默认值实在函数建⽴的时候就⽣成了, 每次调⽤都是⽤了这个对象的”缓存”. 我在上段时间的分享python⾼级编程也说到了这个问题,这个是实际开发遇到的问题,好好检查你学过的代码, 也许只是问题没有暴露
可以这样改:
[url=]复制代码[/url]代码如下:
def append_to_list(element, to=None):
if to is None:
to = []
to.append(element)
return to
⼆、⽣成器不保留迭代过后的结果
[url=]复制代码[/url]代码如下:
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⾥⾯了? 因为调⽤1->2,这个时候1已经不在迭代器⾥⾯了,被按需⽣成过了
In [20]: gen = (i for i in range(5))
In [21]: a_list = list(gen) # 可以转化成列表,当然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 # 就算循环过,值还在
Out[24]: True
三、lambda在闭包中会保存局部变量
[url=]复制代码[/url]代码如下:
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⾼级编程中说过具体原因. 其实就是当我赋值给my_list的时候,lambda表达式就执⾏了i会循环,直到 i =4,i会保留
但是可以⽤⽣成器
[url=]复制代码[/url]代码如下:
In [31]: my_gen = (lambda: n for n in range(5))
In [32]: for l in my_gen:
....: print(l())
....:
1
2
3
4
也可以坚持⽤list:
[url=]复制代码[/url]代码如下:
In [33]: my_list = [lambda x=i: x for i in range(5)] # 看我给每个lambda表达式赋了默认值
In [34]: for l in my_list:
.
...: print(l())
....:
1
2
3
4
有点不好懂是吧,在看看python的另外⼀个魔法:
[url=]复制代码[/url]代码如下:
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)]
⼀个分组的函数,看起来很不好懂,对吧? 我们来解析下这⾥
[url=]复制代码[/url]代码如下:
In [39]: [iter(items)]*3
Out[39]:
[,
,
] # 看到了吧, 其实就是把items变成可迭代的, 重复三回(同⼀个对象哦), 但是别忘了,每次都.next(), 所以起到了分组的作⽤In [40]: [lambda x=i: x for i in range(5)]
Out[40]:
[>,
>,
>,
>,
>] # 看懂了吗?
四、在循环中修改列表项
[url=]复制代码[/url]代码如下:
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] # 本来我想要的结果应该是去除偶数的列表
思考⼀下,为什么 – 是因为你对列表的remove,影响了它的index
[url=]复制代码[/url]代码如下:
In [53]: b = [2, 4, 5, 6]python新手代码错了应该怎么改
In [54]: for index, item in enumerate(b):
....: print(index, item)
....: if not item % 2:
....: b.remove(item)
....:
(0, 2) # 这⾥没有问题 2被删除了
(1, 5) # 因为2被删除⽬前的列表是[4, 5, 6], 所以索引list[1]直接去5, 忽略了4 (2, 6)
五、IndexError - 列表取值超出了他的索引数
[url=]复制代码[/url]代码如下:
In [55]: my_list = [1, 2, 3, 4, 5]
In [56]: my_list[5] # 根本没有这个元素
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
in ()
----> 1 my_list[5]
IndexError: list index out of range # 抛异常了
In [57]: my_list[5:] # 但是可以这样, ⼀定要注意, ⽤好了是trick,⽤错了就是坑啊
Out[57]: []
六、重⽤全局变量
[url=]复制代码[/url]代码如下:
In [58]: def my_func():
.
...: print(var) # 我可以先调⽤⼀个未定义的变量
....:
In [59]: var = 'global' # 后赋值
In [60]: my_func() # 反正只要调⽤函数时候变量被定义了就可以了
global
In [61]: def my_func():
....: var = 'locally changed'
....:
In [62]: var = 'global'
In [63]: my_func()
In [64]: print(var)
global # 局部变量没有影响到全局变量
In [65]: def my_func():
....: print(var) # 虽然你全局设置这个变量, 但是局部变量有同名的, python以为你忘了定义本地变量了....: var = 'locally changed'
....:
In [66]: var = 'global'
In [67]: my_func()
---------------------------------------------------------------------------
UnboundLocalError Traceback (most recent call last)
in ()

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。