这里到底发生了什么?(Python 3.7.6)



我正在研究其他人对Codewars的解决方案,对此有点困惑。以下是原始问题的链接:反转还是旋转?。这要归功于原作者falsetru

解决方案如下:

def revrot(strng, sz):
return ''.join(
chunk[1:] + chunk[:1] if sum(int(d)**3 for d in chunk) % 2 else chunk[::-1]
for chunk in map(''.join, zip(*[iter(strng)]*sz))
)

我想我大部分都懂了。除了这个部分:

zip(*[iter(strng)]*sz)

我认为以这种方式使用的*表示一个无关键字的可变长度参数列表,这意味着原始字符串(strng(可以有任意数量的片段,长度为sz,例如6。根据文档,zip()函数正在接收一些可变数量的可迭代项,这正是它所需要的。(对吗?(

因此,map(''.join, zip(*[iter(strng)]*sz)首先返回字符串strng的迭代器。它在列表中返回这个。这个列表似乎乘以了sz(为什么?(。它向zip(因此是*(返回数量可变的结果。zip()返回一个元组(我想是?(,然后通过map将其传递给join函数。

问题:

  1. 这几乎是对的吗
  2. 为什么iter(strng(必须放在列表[]
  3. 为什么你可以加入zip的结果?我试着加入('m',)作为测试,得到了'm'。困惑于为什么这同样有效
  4. 有人能解释更多关于*的信息吗?我不知道什么时候该用它

谢谢。我还是Python的初学者,所以我很感激你的帮助!(即使只是我的一部分问题!(

要了解发生了什么,我们需要分析语句

for chunk in map(''.join, zip(*[iter(strng)]*sz))

由内而外:

  1. iter(strng)返回迭代器,每次使用next访问该迭代器或在循环中消耗strng的元素(字符(并返回所述元素
  2. [iter(strng)]是一个列表,它的唯一元素是迭代器
  3. [iter(strng)]*sz是列表的sz副本的级联,[iter(strng), ..., iter(strng)]包含sz相同的迭代器对象,我的意思是字面上是相同的迭代器对象
  4. *[iter(strng)]*sz等效于*[iter(strng), ..., iter(strng)],当在函数参数列表中使用时,将其内容解压缩:函数将其参数列表视为(iter(strng), ..., iter(strng))
  5. 因此CCD_ 26等效于CCD_
  6. 在每次迭代中,zip取其每个参数的第一个元素,并将它们放在元组中,但由于对iter的各种引用都引用了iter(strng)的同一原始实例,因此zip返回的第一个元组包含strng的第一个sz字符,第二个元组则包含sz+12*sz字符等
  7. 最后,这些元组中的每一个都是''.join()的自变量,因此我们有一系列字符串,每个字符串都是长sz个字符,跨越原始strng

就是这样。

相关内容

  • 没有找到相关文章

最新更新