• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

关于python:一道题让你从此真正理解Python编程

python 搞代码 3年前 (2022-02-20) 31次浏览 已收录 0个评论

远处传来那首相熟的歌,
那些心声为何那样强劲。
很久不见,你当初都还好吗?
有没有那么一首歌,
会让你微微跟着和,
随着咱们生命起伏,
一起唱的主题歌;
有没有那么一首歌,
会让你忽然想起我,
让你欢喜也让你忧,
这么一个我……

音乐完结,回到正题。近日浏览LeetCode,发现了一道很有意思的小题目。当我尝试用Python解答的时候,竟然动用了汇合、map函数、zip函数、lambda函数、sorted函数,调试过程还波及到了迭代器、生成器、列表推导式的概念。一个看似极为简略的题目,只管最终的代码能够合并成一行,却简直把Python的编程技巧用了一遍,真堪称“轻微之处见精力”!通过这个题目,兴许会让你从此真正了解了Python编程。

这道题,名为《列表中的侥幸数》。什么是侥幸数呢?在整数列表中,如果一个数字的呈现频次和它的数值大小相等,咱们就称这个数字为「侥幸数」。例如,在列表[1, 2, 2, 3]中,数字1和数字2呈现的次数别离是1和2,所以它们是侥幸数,但3只呈现过1次,3不是侥幸数。

明确了侥幸数的概念,咱们就来试着找出列表[3, 5, 2, 7, 3, 1, 2 ,4, 8, 9, 3]中的侥幸数吧。这个过程能够分为以下几个步骤:

  • 找出列表中不反复的数字
  • 统计每个数字在列表中呈现的次数
  • 找出呈现次数等于数字自身的那些数字

第1步,找出列表中不反复的数字

找出列表中不反复的数字,也就是去除列表中的反复元素,简称“去重”。去重最简洁的办法是应用汇合。

<code class="ruby">>>> arr = [3,5,2,7,3,8,1,2,4,8,9,3]



>>> unique = set(arr)



>>> unique



{1, 2, 3, 4, 5, 7, 8, 9}

第2步,统计每个数字在列表中呈现的次数

咱们晓得,列表对象自带一个count()办法,能返回某个元素在列表中呈现的次数,具体用法如下:

<code class="ruby">>>> arr = [3,5,2,7,3,8,1,2,4,8,9,3]



>>> arr.count(8) # 元素8在数组arr中呈现过2次



2

接下来,咱们只须要遍历去重后的各个元素,逐个统计它们各自呈现的次数,并保留成一个适合的数据结构,这一步工作就高枕无忧了。

<code class="ruby">>>> arr = [3,5,2,7,3,8,1,2,4,8,9,3]



>>> unique = set(arr) # 去除反复元素



>>> pairs = list() # 空列表,用于保留数组元素和呈现次数组成的元组



>>> for i in unique:



    pairs.append((i, arr.count(i)))



 



 



>>> pairs



[(1, 1), (2, 2), (3, 3), (4, 1), (5, 1), (7, 1), (8, 2), (9, 1)]

作为老手,代码写成这样,曾经很不错了。然而,一个有谋求的程序员相对不会就此自满、裹足不前。他们最喜爱做的事件就是想尽千方百计毁灭for循环,比方应用映射函数、过滤函数取代for循环;即使不能回绝for循环,他们也会尽可能把循环藏起来,比方藏在列表推导式内。这里既然是要对每一个元素都调用列表的count()这个办法,那就最适宜用map函数取代for循环了。

<code class="ruby">>>> m = map(arr.count, unique)



>>> m



<map object at 0x0000020A2D090E08>



>>> list(m) # 生成器能够转成列表



[1, 2, 3, 1, 1, 1, 2, 1]



>>> list(m) # 生成器只能用一次,用过之后,就主动清理了



[]

map函数返回的是一个生成器(generator),能够像列表一样遍历,但无奈像列表那样直观地看到各个元素,除非咱们用list()把这个生成器转成列表(实际上并不需要将生成器转为列表)。请留神,生成器和迭代器不同,或者说生成器是一种非凡的迭代器,只能被遍历一次,遍历完结,就主动隐没了。迭代器则能够重复遍历。比方,range()函数返回的就是迭代器:

<code class="ruby">>>> a = range(5)



>>> list(a)



[0, 1, 2, 3, 4]



>>> list(a)



[0, 1, 2, 3, 4]

说完生成器和迭代器,咱们还得回到原来的话题上。应用map映射函数,咱们失去了每个元素的呈现次数,还须要和对应的元素组成一个一个的元组。这时候,就用上zip()函数了。zip() 函数创立一个生成器,用来聚合每个可迭代对象(迭代器、生成器、列表、元组、汇合、字符串等)的元素,元素依照雷同下标聚合,长度不同则疏忽大于最短迭代对象长度的元素。

<code class="ruby">>>> m = map(arr.count, unique)



>>> z = zip(unique, m)



>>> z



<zip object at 0x0000020A2D490508>



>>> list(z)



[(1, 1), (2, 2), (3, 3), (4, 1), (5, 1), (7, 1), (8, 2), (9, 1)]



>>> list(z)



[]

很显然,zip()函数返回的也是生成器,只能用一次,过后即隐没。

第3步,找出呈现次数等于数字自身的那些数字

有了每个元素及其呈现的次数,咱们只须要循环遍历……不,请稍等,咱们为什么肯定要循环呢?咱们只是要把每个元素过滤一遍,找出那些呈现次数等于元素本身的那些元组,为什么不试试过滤函数filter()呢?

<code class="ruby">>>> def func(x): # 参数x是元组类型



    if x[0] == x[1]:



      return x



 



 



>>> m = map(arr.count, unique)



>>> z = zip(unique, m)



>>> f = filter(func, z)



>>> f



<filter object at 0x0000020A2D1DD908>



>>> list(f)



[(1, 1), (2, 2), (3, 3)]



>>> list(f)



[]

过滤函数filter()承受两个参数,第1个参数是个函数,用于判断一个元素是否合乎过滤条件,第2个参数就是须要过滤的可迭代对象了。filter()函数返回的也是生成器,只能用一次,过后即隐没。

写这里,咱们简直要功败垂成了。然而,作为一个有谋求的程序员,你能容忍func()这样一个看起来怪怪的函数吗?答案是不能!你肯定会用lambda函数取代它。另外,兴许咱们还须要对后果依照元素的大小排序。加上排序,残缺代码如下:

<code class="ruby">>>> arr = [3,5,2,7,3,8,1,2,4,8,9,3]



>>> unique = set(arr)



>>> m = map(arr.count, unique)



>>> z = zip(unique, m)



>>> f = filter(lambda x:x[0]==x[1], z)



>>> s = sorted(f, key=lambda x:x[0])



>>> print('侥幸数是:', [item[0] for item in s])



侥幸数是:[1, 2, 3]

终极代码,一行搞定

如果你已经有过被那些写成一行、却能实现简单性能的、看起来像天书一样的代码践踏的苦楚经验,那么,当初你也能够把下面的代码写成一行,去践踏他人了。

<code class="swift">>>> arr = [3,5,2,7,3,8,1,2,4,8,9,3]



>>> print('侥幸数是:', [item[0] for item in sorted(filter(lambda x:x[0]==x[1], zip(set(arr), map(arr.count, set(arr)))), key=lambda x:x[0])])



侥幸数是:[1, 2, 3]

戏剧性反转,这次真的了解Python了!

有人说,何必那么麻烦呢?这样写不是更简略、更易读吗?果然,我真是想多了!

<code class="shell">>>> arr = [3,5,2,7,3,8,1,2,4,8,9,3]



>>> [x for x in set(arr) if x == arr.count(x)]

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:关于python:一道题让你从此真正理解Python编程

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址