在 perl 中使用嵌套映射是一种好习惯吗?
Posted
技术标签:
【中文标题】在 perl 中使用嵌套映射是一种好习惯吗?【英文标题】:Is using nested map in perl a good practice? 【发布时间】:2012-10-06 16:33:40 【问题描述】:my @c= map
my $v=$_;
map $_ * $v @m
@a;
这样使用map
是个好习惯吗?为什么不?
如果没有,还有其他方法吗?
【问题讨论】:
不要像for-loop
那样使用map
,它是列表修饰符。
map
不仅是一个列表修饰符,还是一个列表生成器。这就是他的例子所显示的。不过,您的评论对于 map print @list
之类的内容是正确的。
@Moritz,“列表修饰符”是一个非常适用的术语。 map
输出的列表直接基于传递给它的列表。 (不过,我同意其余的观点。map
不会在 void 上下文中被调用。)
我在 void 上下文中看到很多关于 map
的 cmets,但我很确定我已经读到该构造中的性能问题已得到修复。 ***.com/a/4174537/468327(p.s.此评论与可读性无关)
@ikegami 好的,授予。我在想这样一个事实,即在地图内部 $_
是一个允许修改原始列表的别名。含义@l = (1, 2); map $_ += 1 @l; # @l is now (2, 3)
【参考方案1】:
嵌套map
与任何其他嵌套结构具有相同的问题和相同的解决方案,除了因需要重新分配$_
而略有放大。嵌套的map
不流动的事实是代码异味:您的代码试图告诉您应该稍微不同的结构。
并且适当的更改是将内部操作变成函数调用,这样读者就不必同时跟踪两个作用域。在这种情况下,您会得到:
sub scale
my ($factor, @numbers) = @_;
return map $factor * $_ @numbers;
my @c = map scale($_, @m) @a;
【讨论】:
这里有很多设置/拆卸,您对sub scale my $factor = shift; return map $factor * $_ @_
满意吗?
当然;这几乎是一个风格问题。我倾向于始终使用一种或另一种形式,除非我的分析告诉我一致性会影响性能,但这真的只是我自己。【参考方案2】:
我一直对map
命令有复杂的感觉。使用map
有很多陷阱,这也是让 Python 人对 Perl 的不可读性幸灾乐祸的原因之一。此外,map
并不比使用常规循环更有效。
当 map 修改 $_
的值时,有一个 gotcha,因为它实际上只是原始数组中值的别名。修改$_
,你就修改了你原来的数组。也许这就是您想要的,但 map
命令可能会掩盖这一点。 Perl Monks 中有一个关于 map
的讨论。
即使您在map
中使用map
确实有效(map
确实为您本地化了$_
,所以$_
在一个map
中与$_
中的不同其他map
),还有可读性和可维护性的问题。
只有在用法清晰且易于理解上下文时才使用map
。保存电子邮件签名的聪明 Perl 技巧。我不会使用地图内地图。
【讨论】:
我明白你关于 python 感知的观点,但我发现列表推导同样难以理解。 那个“陷阱”也适用于for
,以及所有列表元素有别名的循环结构。这不是特定于map
,而是可能特定于perl。我也不同意map
包含陷阱,也许您应该通过一些示例来验证该声明。
这不是错误。这是一个特点!看到它是documented!当你在文档中看到描述副作用的词 bizarre 时,你就有问题了。当你必须做一些奇怪的语法咒语,以便 Perl 可以正确解析你的语句时,你就有了陷阱。将 map 的文档与 Foreach loops 的文档进行比较。此外,双地图将是一个维护头痛。当你必须开始像编译器一样思考时,你就有问题了。
单词“bizarre”被限定为“如果 LIST 的元素不是变量”。这同样适用于 for 循环。试试perl -e 'print ++$_ for 1,2,3'
。你提到的这些“奇怪的语法咒语”是什么?【参考方案3】:
我无法回答这是否是好的做法。一般来说,在很多情况下,我会大量使用嵌套地图。它很简短,简洁明了。
然而,这样的嵌套地图总是有变得有点太大和笨拙的危险,在这种情况下它们变得比它们必须的更难阅读($_
在这种情况下指的是哪个列表!?)。所以使用它们,是的,但要谨慎使用——就像所有其他使 Perl 如此简洁和富有表现力的类似事物一样。
【讨论】:
【参考方案4】:我不确定你的意思。它会很好地工作,还是您在询问可读性?与等效的 foreach 循环相比,阅读较长的 map
可能会更加困难。
my @c;
for my $v (@a)
push @c, map $_ * $v @m;
【讨论】:
执行时间如何?loop
或 map
哪个更快?如果我使用 perl 脚本进行大量数据处理,loop
会减慢执行速度吗?在这种情况下map
会更好吗?以上是关于在 perl 中使用嵌套映射是一种好习惯吗?的主要内容,如果未能解决你的问题,请参考以下文章