wtfPython—Python中一组有趣微妙的代码【收藏】


Posted in Python onAugust 31, 2018

wtfPython是github上的一个项目,作者收集了一些奇妙的Python代码片段,这些代码的输出结果会和我们想象中的不太一样;

通过探寻产生这种结果的内部原因,可以让我们对Python里的一些细节有更广泛的认知。

1.字典键的隐式转换

some_dict = {}
some_dict[5.5] = "Ruby"
some_dict[5.0] = "JavaScript"
some_dict[5] = "Python"

输出如下:

>>> some_dict
{5.0: "Python", 5.5: "Ruby"}
>>> some_dict[5.5]
"Ruby"
>>> some_dict[5.0]
"Python"
>>> some_dict[5]
"Python"

原因:

Python的字典键的比较是通过哈希值来比较的

在Python里如果两个不可变对象的值相等,那他们的哈希也是一样的

因此此处hash(5) == hash(5.0)是True的,所以键被隐式的转换了

2.生成器执行时间的差异

array = [1, 8, 15]
g = (x for x in array if array.count(x) > 0)
array = [2, 8, 22]

输出:

>>> print(list(g))
[8]

原因

在一个生成器表达式里,in的操作是在声明时求值的,而if是在运行期求值的

所以在运行期之前,array已经被重新分配成了[2,8,22],x的值也是2,8,22

3.在列表迭代式删除item

list_1 = [1, 2, 3, 4]
list_2 = [1, 2, 3, 4]
list_3 = [1, 2, 3, 4]
list_4 = [1, 2, 3, 4]
for idx, item in enumerate(list_1):
 del item
for idx, item in enumerate(list_2):
 list_2.remove(item)
for idx, item in enumerate(list_3[:]):
 list_3.remove(item)
for idx, item in enumerate(list_4):
 list_4.pop(idx)

输出:

>>> list_1
[1, 2, 3, 4]
>>> list_2
[2, 4]
>>> list_3
[]
>>> list_4
[2, 4]

原因

其实只有list3才算是合格的写法,对一个正在迭代的对象进行修改并不是一个很好的选择,正确的做法应该是建立一份该对象的拷贝来进行迭代

对于list1,del item删除的只是item变量而不是变量指向的数据,对列表本身没有影响

对于list2和list4,因为列表的迭代是根据索引来的,第一次删掉了索引为0的1,剩下[2, 3, 4],然后移除索引 1(此时为3),剩下了[2, 4],此时只有2个元素,循环结束

4.else的不同处理

对于循环的else

def does_exists_num(l, to_find):
  for num in l:
   if num == to_find:
    print("Exists!")
    break
  else:
   print("Does not exist")

输出:

>>> some_list = [1, 2, 3, 4, 5]
>>> does_exists_num(some_list, 4)
Exists!
>>> does_exists_num(some_list, -1)
Does not exist

对于try的else

try:
 pass
except:
 print("Exception occurred!!!")
else:
 print("Try block executed successfully...")

输出:

Try block executed successfully...

原因

循环后的else只会在经过了所有迭代且没有出现break的时候才会执行

一个try模块后的else会在try里的代码成功执行完后去执行

5.python里的is

>>> a = 256
>>> b = 256
>>> a is b
True
>>> a = 257
>>> b = 257
>>> a is b
False

原因

is和==是不一样的;is判断的是两个对象是否是同一个对象,而==判断的是两个对象的值是否相等;即is是既要值相等又要引用一致

在Python中-5~256因为被经常使用所以被设计成固定存在的对象

6.循环里的局部变量泄露

代码段1

for x in range(7):
 if x == 6:
  print(x, ': for x inside loop')
print(x, ': x in global')

输出:

6 : for x inside loop
6 : x in global

代码段2

# This time let's initialize x first
x = -1
for x in range(7):
 if x == 6:
  print(x, ': for x inside loop')
print(x, ': x in global')

输出:

6 : for x inside loop6 : x in global

代码段3

x = 1
print([x for x in range(5)])
print(x, ': x in global')

在Python2.x里的输出:

[0, 1, 2, 3, 4](4, ': x in global')

在Python3.x里的输出:

[0, 1, 2, 3, 4]1 : x in global

原因

对于代码段1,在Python中,for循环可以使用包含他们的命名空间的变量,并将他们自己定义的循环变量保存下来;* 对于代码段2,如果我们在全局命名空间里显示定义for循环变量,则循环变量会重新绑定到现有变量上。

对于代码段3,在Python3.x中改变了对列表解析的语法形式;Python2.x中,列表解析的语法形式为:[… for var in item1, item2, …];而Python3.x的列表解析式为:[… for var in (item1, item2, …)],这种情况下不会发生循环变量的泄露

7.+和+=的区别

代码段1

a = [1, 2, 3, 4]
b = a
a = a + [5, 6, 7, 8]

输出:

>>> a
[1, 2, 3, 4, 5, 6, 7, 8]
>>> b
[1, 2, 3, 4]

代码段2

a = [1, 2, 3, 4]
b = a
a += [5, 6, 7, 8]

输出:

>>> a
[1, 2, 3, 4, 5, 6, 7, 8]
>>> b
[1, 2, 3, 4, 5, 6, 7, 8]

原因

a = a + b的操作生成了一个新的对象并建立了一个新的引用

a += b是在a这个列表上做extend操作

8.关于try—finally里的return

def some_func():
  try:
    return 'from_try'
  finally:
    return 'from_finally'

输出:

>>> some_func()
'from_finally'

原因

在try…finally这种写法里面,finally中的return语句永远是最后一个执行

一个函数的return的值是由最后一个return语句来决定的

9.True=False

True = False
if True == False:
  print("I've lost faith in truth!")

输出:

I've lost faith in truth!

原因

最开始的时候,Python是没有bool类型的(使用0表示false,使用非0值表示真),后来加上了True,False和bool类型;但是为了向后兼容性,True和False并没有被设置成常量,而只是一个内建变量,所以可以被赋值修改
在Python3当中,因为并没有向后兼容,所以不会有这种情况发生

10.一步操作,从有到无

some_list = [1, 2, 3]
some_dict = {
 "key_1": 1,
 "key_2": 2,
 "key_3": 3
}
some_list = some_list.append(4)
some_dict = some_dict.update({"key_4": 4})

输出:

>>> print(some_list)
None
>>> print(some_dict)
None

原因

许多修改序列/映射对象的方法(例如list.append, dict.update, list.sort等等)都是直接修改对象并返回一个None;所以平常碰到这种直接修改的操作,应该避免直接赋值。

11.Python的for

for i in range(4):
  print(i)
  i = 10

输出:

0
1
2
3

原因

Python的for循环机制是每次迭代到下一项的时候都会解包并分配一次;即range(4)里的四个值在每次迭代的时候都会解包一次并赋值;所以i = 10对迭代没有影响。

总结

以上所述是小编给大家介绍的wtfPython—Python中一组有趣微妙的代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
跟老齐学Python之不要红头文件(2)
Sep 28 Python
Python实现对PPT文件进行截图操作的方法
Apr 28 Python
python 的列表遍历删除实现代码
Apr 12 Python
Python实现的排列组合计算操作示例
Oct 13 Python
使用python为mysql实现restful接口
Jan 05 Python
Tensorflow环境搭建的方法步骤
Feb 07 Python
详解python中的json和字典dict
Jun 22 Python
Django 重写用户模型的实现
Jul 29 Python
Django配置MySQL数据库的完整步骤
Sep 07 Python
如何定义TensorFlow输入节点
Jan 23 Python
jupyter note 实现将数据保存为word
Apr 14 Python
关于Numpy之repeat、tile的用法总结
Jun 02 Python
opencv python 图像去噪的实现方法
Aug 31 #Python
python+numpy+matplotalib实现梯度下降法
Aug 31 #Python
python实现随机梯度下降法
Mar 24 #Python
python实现决策树分类(2)
Aug 30 #Python
python实现决策树分类
Aug 30 #Python
python实现多人聊天室
Mar 31 #Python
Python实现将数据写入netCDF4中的方法示例
Aug 30 #Python
You might like
历史证明,懒惰才是推动科学发展技术进步的动力
2021/03/02 无线电
Pain 全世界最小最简单的PHP模板引擎 (普通版)
2011/10/23 PHP
PHP使用Pthread实现的多线程操作实例
2015/11/14 PHP
Yii2中添加全局函数的方法分析
2017/05/04 PHP
Thinkphp 框架扩展之Widget扩展实现方法分析
2020/04/23 PHP
JQUERY CHECKBOX全选,取消全选,反选方法三
2008/08/30 Javascript
jQuery实战之仿淘宝商城左侧导航效果
2011/04/12 Javascript
js如何获取兄弟、父类等节点
2014/01/06 Javascript
js格式化时间和js格式化时间戳示例
2014/02/10 Javascript
在Linux上用forever实现Node.js项目自启动
2014/07/09 Javascript
AngularJS 依赖注入详解和简单实例
2016/07/28 Javascript
vue开发心得和技巧分享
2016/10/27 Javascript
JavaScript数组去重的6个方法
2017/01/21 Javascript
Node.js实现发送邮件功能
2017/11/06 Javascript
vue-cli webpack2项目打包优化分享
2018/02/07 Javascript
angularjs 获取默认选中的单选按钮的value方法
2018/02/28 Javascript
详解50行代码,Node爬虫练手项目
2019/04/22 Javascript
python里将list中元素依次向前移动一位
2014/09/12 Python
Python图像处理之简单画板实现方法示例
2018/08/30 Python
NLTK 3.2.4 环境搭建教程
2018/09/19 Python
深入理解Python异常处理的哲学
2019/02/01 Python
Python正则表达式和re库知识点总结
2019/02/11 Python
python tkinter组件使用详解
2019/09/16 Python
中国最大的名表商城:万表网
2016/08/29 全球购物
海外淘书首选:AbeBooks
2017/07/31 全球购物
Clarria化妆品官方网站:购买天然和有机化妆品系列
2018/04/08 全球购物
Moda Italia荷兰:意大利男士服装
2019/08/31 全球购物
Linux如何修改文件和文件夹的权限
2013/09/05 面试题
php优化查询foreach代码实例讲解
2021/03/24 PHP
毕业晚会主持词
2014/03/24 职场文书
汽车运用工程专业求职信
2014/06/18 职场文书
用人单位终止解除劳动合同证明书
2014/10/06 职场文书
钱学森观后感
2015/06/04 职场文书
酒店厨房管理制度
2015/08/06 职场文书
2019生态环境保护倡议书!
2019/07/03 职场文书
小学生必读成语故事大全:送给暑假的你们
2019/07/09 职场文书