鱼C论坛

 找回密码
 立即注册
查看: 2787|回复: 4

[已解决]不理解代码的含义 list(zip(*[iter([1, 2, 3, 4, 5, 6, 7, 8, 9])] * 3))

[复制链接]
发表于 2022-10-15 20:41:07 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
浏览论坛看到的一篇小甲鱼发布的问题,还是有点不理解。原链接 https://fishc.com.cn/thread-140340-1-1.html

首先是拆解开的答案:

>>> x = iter([1,2,3,4,5,6,7,8,9])
>>> list(zip(x, x, x))

第2行的zip(x,x,x)不太理解。是指第一个x为iter([1,2,3,4,5,6,7,8,9]),取出了"1";第二个x为iter([2,3,4,5,6,7,8,9]),取出了"2",一直到最后吗?



然后是最后的答案:

>>> list(zip(*[iter([1, 2, 3, 4, 5, 6, 7, 8, 9])] * 3))
[(1, 2, 3), (4, 5, 6), (7, 8, 9)]

第一个"*"是什么意思,如果可以的话再告诉我是具体哪节课的知识点。然后第一个"*"的的运算是晚于"*3"的,对吧?




第一次发帖,希望来个好人帮帮忙,谢谢了。
最佳答案
2022-10-16 11:53:52
第一个x为iter([1,2,3,4,5,6,7,8,9]),取出了"1";第二个x为iter([2,3,4,5,6,7,8,9]),取出了"2",一直到最后吗?

答案是肯定的,确实如你所理解的那样。具体过程还是分步骤拆解来理解吧。

首先看最里层的iter([1, 2, 3, ...9]),这是在调用iter把列表转为迭代器;

然后是[iter([1, 2, 3, ...9])]*3,首先把上一步生成的迭代器组成一个列表,然后*3就是把列表中的元素拷贝为3份,此时列表中的元素是三个相同的迭代器,类似这样:[iter([1, 2, 3, ...9]), iter([1, 2, 3, ...9]), iter([1, 2, 3, ...9])]。切记,这个列表中的三个迭代器是完全相同的;

接下来是*[iter([1, 2, 3, ...9]), iter([1, 2, 3, ...9]), iter([1, 2, 3, ...9])]。正如你预期的那样,列表前面的这个星号运算优先级确实低于乘号,作用是解包。解包之前列表中的所有元素构成了一个整体,解包后成为一个个独立的元素。此处之所以要解包是为了把上个步骤中列表的三个迭代器都传给zip。来看看加不加这个解包用的星号的区别吧:
>>> x = iter([1, 2, 3, ...9])
>>> y = [x, x, x]
>>> zip(*y)  # 等价于zip(x, x, x)
>>> zip(y)  # 等价于zip([x, x, x])

最后list从zip(x, x, x)中取值并组成一个列表,zip每次返回的都是一个元组,所以你可以看到列表中的每个元素都是包含三个数字的元组。
之所以每个元组都有三个数字,是因为zip把传入的三个迭代器iter([1, 2, 3, ...9])进行对齐处理,每次都从这三个迭代器中各取一个数字组成一个元组,并且把这个元组给到list。
为什么1,2,3是一个元组,4,5,6又是另外一个元组呢?前面解释列表拷贝操作的时候说过了,列表中的三个迭代器其实是同一个对象的三个副本,它们完全相同!所以表面上看zip每次从三个迭代器中取出一个值,可实际效果却是从同一个迭代器中一次取三个值,如此一来列表[1, 2, 3, ...9]就恰好被分成了三份了。这是背后的原理
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-10-16 11:53:52 | 显示全部楼层    本楼为最佳答案   
第一个x为iter([1,2,3,4,5,6,7,8,9]),取出了"1";第二个x为iter([2,3,4,5,6,7,8,9]),取出了"2",一直到最后吗?

答案是肯定的,确实如你所理解的那样。具体过程还是分步骤拆解来理解吧。

首先看最里层的iter([1, 2, 3, ...9]),这是在调用iter把列表转为迭代器;

然后是[iter([1, 2, 3, ...9])]*3,首先把上一步生成的迭代器组成一个列表,然后*3就是把列表中的元素拷贝为3份,此时列表中的元素是三个相同的迭代器,类似这样:[iter([1, 2, 3, ...9]), iter([1, 2, 3, ...9]), iter([1, 2, 3, ...9])]。切记,这个列表中的三个迭代器是完全相同的;

接下来是*[iter([1, 2, 3, ...9]), iter([1, 2, 3, ...9]), iter([1, 2, 3, ...9])]。正如你预期的那样,列表前面的这个星号运算优先级确实低于乘号,作用是解包。解包之前列表中的所有元素构成了一个整体,解包后成为一个个独立的元素。此处之所以要解包是为了把上个步骤中列表的三个迭代器都传给zip。来看看加不加这个解包用的星号的区别吧:
>>> x = iter([1, 2, 3, ...9])
>>> y = [x, x, x]
>>> zip(*y)  # 等价于zip(x, x, x)
>>> zip(y)  # 等价于zip([x, x, x])

最后list从zip(x, x, x)中取值并组成一个列表,zip每次返回的都是一个元组,所以你可以看到列表中的每个元素都是包含三个数字的元组。
之所以每个元组都有三个数字,是因为zip把传入的三个迭代器iter([1, 2, 3, ...9])进行对齐处理,每次都从这三个迭代器中各取一个数字组成一个元组,并且把这个元组给到list。
为什么1,2,3是一个元组,4,5,6又是另外一个元组呢?前面解释列表拷贝操作的时候说过了,列表中的三个迭代器其实是同一个对象的三个副本,它们完全相同!所以表面上看zip每次从三个迭代器中取出一个值,可实际效果却是从同一个迭代器中一次取三个值,如此一来列表[1, 2, 3, ...9]就恰好被分成了三份了。这是背后的原理
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2022-10-16 20:27:59 | 显示全部楼层
Brick_Porter 发表于 2022-10-16 11:53
答案是肯定的,确实如你所理解的那样。具体过程还是分步骤拆解来理解吧。

首先看最里层的iter([1, 2,  ...

嗯嗯,大佬讲的很明白,感谢大佬。我还有个想确认的问题是:因为x是迭代器,所以zip(x,x,x)每次只依次取x的一个值,所以才有(1,2,3)(4,5,6)(7,8,9),而不是同时取值得到(1,1,1)(2,2,2)这样,是可以这样理解的对吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-10-16 21:17:57 | 显示全部楼层
本帖最后由 Brick_Porter 于 2022-10-16 21:34 编辑
whx_py 发表于 2022-10-16 20:27
嗯嗯,大佬讲的很明白,感谢大佬。我还有个想确认的问题是:因为x是迭代器,所以zip(x,x,x)每次只依次取x ...


虽然只有一行代码,但是背后的逻辑其实挺复杂的。
每一次zip(x, y, z)都会分别从x、y、z中取一个值,组成一个元组,然后返回这个元组。所以其实我们期望的结果应该是(1, 1, 1)、(2, 2, 2)……这样的,但是我们的代码zip(x, x, x)中的三个x是完全相同的,换言之它们就是同一个迭代器对象,而zip每次又要返回3个元素组成的元组。由于这个巧合的存在所以实际输出为(1, 2, 3)、(4, 5, 6)……

zip是一个类,用来“压缩”多个可迭代对象,所谓的压缩就是我前面说的“对齐”,注意看下面的代码:
>>> x = [1, 2, 3]
>>> y = ('a', 'b', 'c', 'd')
>>> z = [True, False, False]
>>> result = zip(x, y, z)  # 尽管x、y、z三个对象长度不等也可以对齐,按照最短的来处理
>>> for i in result:
>>>     print(i)
(1, 'a', True)
(2, 'b', False)
(3, 'c', False)
当你需要同时处理多个可迭代对象的时候就可以用到zip了

iter其实也是一个类而不是函数,它的作用也挺复杂的,因为它的关系导致了最后的输出结果为(1, 2, 3)、(4, 5, 6)……iter也是个黑魔法,如果还有疑问请留言
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-10-17 16:03:49 | 显示全部楼层
Brick_Porter 发表于 2022-10-16 21:17
虽然只有一行代码,但是背后的逻辑其实挺复杂的。
每一次zip(x, y, z)都会分别从x、y、z中取一个值, ...

感谢,完全明白了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-14 22:59

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表