迷惑行为

迷惑行为

最近社团被要求写科技推送,第一稿还被打回了,理由是讲的太难了。绝了,给了别的社团的范文,我细品:

我打开 word 文件一看,这别的社团正文里没有知识,歪歪斜斜的每页上都写着”学习xx,参考xx”几句话。我横竖品不出来,仔细看了半小时,才从字缝里看出字来,满篇都写着的是”可以保研”!

我写好了新的一版,文笔不好,放出来让大火乐乐:

下面是正文:

在家也要打牢 Python 基础!

疫情期间,虽然我们无法返回学校,但是这不影响我们在家坚持学习。

如果你觉得 c,c++ 深奥难懂,java 各种类记得异常痛苦,go,js 只停留在会拼写上。不妨来试试学习 Python,这是一门简洁优美,方便高效的语言,学习的门槛低,上手容易,工具支持多,在科研领域人工智能也有出色的第三方库支持。

学习 Python 的渠道有太多了,但下面两个网址一定要常用常看:

具体怎么样才算 “学懂” Python 了呢,不同人对这句话的理解是不一样的。只把语言当做工具用的小伙伴们会说会用就行,基础语法会写就是”学懂了”,但当真正的问题出现时,仅仅只会简单的语法并不能帮助你解决问题。

我的建议是多去深入理解语言背后的一些内部机制,而不是会了点语法就沾沾自喜。当然语言的内部很复杂,我们学习的时候找准一个点切入,一点一点的学习即可。

还有很重要的一点是:从现在开始去留心自己程序中出现的 bug,有些你想当然的结果往往和最终程序的运行结果不同,这时就需要你发现背后的原因,而不是仅仅修复这个问题。

正文

宅家期间闲来无事,不如花 5-10 min 和我一起看看这些有趣的 Python 例子。

提示:请确保你接触过一些 Python,我们不会提及 Python 最最最基础的东西,那样就太无趣了。

What Happened in my PYTHON?

今天是一个阳光明媚的一天,当我正打算开心的开始写 Python 代码的时候,一条 QQ 消息突然蹦了出来,原来是我的朋友找我:

你这个朋友是不是你自己

朋友: xxx,你是计算机专业的吧
我:是啊,怎么了
朋友:你学过 python 是吗
我:是的
朋友:太好了,我最近也在学,刚好有些问题搞不明白,希望你能帮帮我

我心想,Python 入门起来应该很容易的啊,只要熟悉掌握字典,列表,元组的操作就可以很舒适的使用了啊?会有什么问题呢?

我催促着他贴出来了问题,让我们来看看:

Q1:Same?

1
2
3
4
5
6
7
8
>>> a = dict()
>>> a[5.0] = "Python"
>>> a["5.0"] = "Java"
>>> a
{5.0: 'Python', '5.0': 'Java'}
>>> a[5] = "Ruby"
>>> a
{5.0: 'Ruby', '5.0': 'Java'}

我的好朋友表示很不理解,5.0 怎么能和 5 一样呢?

结果难道不是应该为:

{5.0: 'Python', '5.0': 'Java', 5: 'Ruby'}

Why?

这个问题有对于字典一类的映射数据结构的本质有一定的了解就不会产生迷惑:

我们首先要知道,在 Python 中,为了快速比较字典的键来查找对象,Python 字典通过检查键值是否相等和比较哈希值来确定两个键是否相同。

首先,”哈希值” 是什么,简单来说就是通过一个记录的存储位置和它的关键字之间建立一个确定的对应关系 f将关键字映射后得到的一个值,一般情况下具有独一无二性。展开叙述并不在我们的讨论范围内,有需要的自行百度解决。

  • 具有相同值的不可变对象在 Python 中始终具有相同的哈希值,但这并不意味着哈希值可以唯一确定字典的键,具有不同值的对象也可能具有相同的哈希值(哈希冲突)

那我们回到这个问题,我们可以大胆的猜测,1 和 1.0 的 哈希值是一样的!不然就无法得到这样的结果,你的 Python 解释器不会出错!

验证一下,确实是这样的:

1
2
3
4
>>> 5 == 5.0
True
>>> hash(5) == hash(5.0)
True

Q2:I thought “for .. in range” is same as for statement in C!

朋友没有放过我,问出了下一个问题:

朋友:C 语言的 for(i=0;i<n;i++) 循环和 Python for i in range(n) 循环次数是一样的吧
我:对的,怎么了

他给出了他写的代码:

1
2
3
4
5
6
7
8
for i in range(4):
print(i)
i = 10
# output
# 0
# 1
# 2
# 3

朋友表示:这个循环难道不会只运行一次?

Why?

看起来似乎很有道理。但在 Python 的 for 语句中,可迭代对象的每一项都会执行一个赋值操作。在每次迭代开始之前,迭代器(这里指 range(4))生成的下一个元素就被赋值给目标变量(i)了,所以赋值语句 i = 10 并不会影响迭代。

对于 for 循环的官网解释

什么,你问我什么是迭代器?建议重新学一遍 python 的 for 语句 -_-||

简单的来说,迭代就是重复同样的操作通过当前元素得到下一个元素的操作,就想我们迭代函数一样。

迭代器就是迭代取值的工具,它允许迭代操作。

Q3: I only revise ONE VALUE in the matrix!

我朋友说他想创建一个 3x3 的数组,但又嫌弃嵌套一堆列表太不好看,于是他查到了这样一个神奇的代码:

1
2
3
4
row = [""] * 3
matrix = [row] * 3
print(matrix)
# [['', '', ''], ['', '', ''], ['', '', '']]

看起来不错,优美简洁,Pythonic,但是问题也来了

1
2
3
4
5
6
7
8
9
>>> row = [""] * 3
>>> matrix = [row] * 3
>>> print(matrix)
[['', '', ''], ['', '', ''], ['', '', '']]
>>> matrix[0][0]
''
>>> matrix[0][0] = 1
>>> print(matrix)
[[1, '', ''], [1, '', ''], [1, '', '']]

wt? 我就修改了一个元素啊???

Why?

可以,这很 c 语言。这个问题涉及到很多高级语言的一个知识:深浅复制

对于 Python,当你使用复制语句的时候 a=b,实际上并非开辟了新的内存空间来将 b 的值完全复制过去,Python 的解释器仅仅只是给 b 添加了一个新的引用(或者说指针)。回到上面的问题,这里*实现的就是一个浅复制,在内存空间中上面问题是这样的:

内存分布

很明显,你的数组仅仅只有三个基本元素,其余的都是对这些元素的引用,所以当你修改这三个中的任意一个时,会连带三行的元素都进行修改。

那应该怎么写?

1
2
3
4
>>> matrix = [['']*3 for i in range(3)]
>>> matrix[0][0] = 1
>>> matrix
[[1 , '', ''], ['', '', ''], ['', '', '']

或者老老实实的写[["","",""],["","",""],["","",""]]

Fin

我的朋友心满意足。 智商 + N,满足 + N

关于我们

我是谁?信息科学学院爱特工作室社团的一员

(:

爱特是干什么的?爱特工作室成立于 2002 年,是一个以计算机技术人才培养,网站开发为特色,的技术性团体。工作室设有前端开发,程序开发,UI设计,APP开发,游戏开发五个部门,并通过技术培训、以老带新等方式,不断提升团队成员的技术水平。这里小伙伴和你一起肝项目,放飞你的想象力,也有大佬带你原地起飞。目前程序部开发的语言是 Python,如果你喜欢 Python 也喜欢 web 开发,我们欢迎你的加入。

(*\^o\^)人(\^o\^*)

官网(报名系统已经关闭)www.itstudio.club

):

我们的新生培训讲课同样也对外开放,欢迎任何感兴趣的同学,具体事项可以联系蔡同学(QQ:3519161997)

(。-ω-)zzz

附我的博客地址https://cyx0706.github.io/

(=´ω`=)

Author

Ctwo

Posted on

2020-03-16

Updated on

2020-10-25

Licensed under

Comments