【问题标题】:What exactly is going on here? (Python 3.7.6)这里到底发生了什么? (Python 3.7.6)
【发布时间】:2021-03-18 05:33:21
【问题描述】:

我正在研究其他人在 Codewars 上的解决方案,对某事感到有些困惑。这是原始问题的链接:Reverse or Rotate?。感谢原作者 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 的后期初学者,因此感谢您的帮助! (即使只是我的一个问题!)

【问题讨论】:

  • 这是用于 stackoverflow.com/questions/312443/… 的技术之一。但总的来说,“请向我解释这段代码”并不适合 Stack Overflow,因为很难理解是什么阻止了你自己弄清楚,而且因为混乱有多个方面(即“需要更加专注”)。
  • 嗨,卡尔,很抱歉。下次我肯定会更加专注和具体。我应该把这篇文章分成更小的问题并单独发布吗?另外,感谢您提供该链接;我会仔细看看。

标签: python iterator iterable keyword-argument variable-length


【解决方案1】:

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

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

由内而外:

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

就是这样。

【讨论】:

  • 非常感谢,非常清楚。我很感激。
猜你喜欢
  • 1970-01-01
  • 2012-11-12
  • 1970-01-01
  • 1970-01-01
  • 2010-12-22
  • 2012-08-29
  • 2020-03-12
  • 1970-01-01
相关资源
最近更新 更多