我的任务是将一些代码从Perl转换为Python,然后遇到了使我感到困惑的这段代码:
my $length = map $_, $root =~ /(.)/gs;
通过变量名和测试,我确定它可以获取字符串的长度,但这似乎是一种非常奇怪且难以理解的方法。有什么理由为什么有人会用它来代替this post中提到的length($root)
或可怕的$root =~ y///c
?我想确保我不会因为某些我不知道的奇怪Perl行为而丢失某些功能。
答案 0 :(得分:3)
在列表上下文中,带有/ g修饰符的m //运算符返回所有捕获的列表,在这种情况下,该捕获是字符串中的每个字符。该映射是无操作的,但在标量上下文中返回它将在其生成的列表中包含的元素数,因此结果是字符串中的字符数。 m //运算符在标量上下文中的工作方式不同,因此需要此中间步骤。一个类似的习惯用法是:
[<function Foo.m1 at 0x1171e4e18>, <function Foo.m2 at 0x1171e4268>]
这通常用于更复杂的匹配计数,因为length函数非常适合且效率更高。
答案 1 :(得分:3)
我能想到的唯一区别是,在5.6.x损坏的Unicode模型下,length()返回字符数,而/(.)/gs返回字节数。从5.8.0开始,两者都返回字符数。 5.6.0是19年前发布的,而5.8.0是17年前发布的。
答案 2 :(得分:1)
我不确定原始编码者为什么采用这种“长”方法来获得$root
的长度。
让我逐段剖析代码:
下面的代码将返回一个列表,其中包含$root
中与.
匹配的每个字符(基本上是每个字符)。
$root =~ /(.)/gs
然后映射生成的列表,这基本上什么也不做。在标量上下文中,map将返回元素数:
map $_, (list)
然后,此值存储在$length
中。