我正在研究其他人对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
函数。
问题:
- 这几乎是对的吗
- 为什么iter(strng(必须放在列表
[]
中 - 为什么你可以加入
zip
的结果?我试着加入('m',)
作为测试,得到了'm'
。困惑于为什么这同样有效 - 有人能解释更多关于*的信息吗?我不知道什么时候该用它
谢谢。我还是Python的初学者,所以我很感激你的帮助!(即使只是我的一部分问题!(
要了解发生了什么,我们需要分析语句
for chunk in map(''.join, zip(*[iter(strng)]*sz))
由内而外:
iter(strng)
返回迭代器,每次使用next
访问该迭代器或在循环中消耗strng
的元素(字符(并返回所述元素[iter(strng)]
是一个列表,它的唯一元素是迭代器[iter(strng)]*sz
是列表的sz
副本的级联,[iter(strng), ..., iter(strng)]
包含sz
次相同的迭代器对象,我的意思是字面上是相同的迭代器对象*[iter(strng)]*sz
等效于*[iter(strng), ..., iter(strng)]
,当在函数参数列表中使用时,将其内容解压缩:函数将其参数列表视为(iter(strng), ..., iter(strng))
- 因此CCD_ 26等效于CCD_
- 在每次迭代中,
zip
取其每个参数的第一个元素,并将它们放在元组中,但由于对iter
的各种引用都引用了iter(strng)
的同一原始实例,因此zip
返回的第一个元组包含strng
的第一个sz
字符,第二个元组则包含sz+1
到2*sz
字符等 - 最后,这些元组中的每一个都是
''.join()
的自变量,因此我们有一系列字符串,每个字符串都是长sz
个字符,跨越原始strng
就是这样。