我正在寻找与以下 Python 代码等效的 PHP 代码:
d = {a*2:a*3 for a in range(5)}
这是一个丑陋的单行解决方案:
$d = array_combine(array_map(function ($x) {return $x*2;}, range(0,4)), array_map(function ($x) {return $x*3;}, range(0,4)));
这是一个使用循环的更具可读性的解决方案:(
$d = [];
foreach(range(0,4) as $x) {
$d[$x*2] = $x*3;
}
在 PHP 中是否有更简单更好的方法来做到这一点?
PHP 中没有字典理解语法。当寻找最短和/或最有效的代码来产生相同的输出时,我建议这样做:
您可以使用 range 函数的第三个参数:
$d = array_combine (range(0,8,2), range(0,12,3));
var_export($d)
的输出:
array (
0 => 0,
2 => 3,
4 => 6,
6 => 9,
8 => 12,
)
当然,这仅在你的表达式是线性的情况下才有效。
foreach
foreach
循环确实是处理这个问题最干净、最易读的方法。请注意,您的版本中有一个小错误:range函数至少需要 2 个参数。
此外,PHP 不要求您初始化 $d,因为它会在循环中第一次赋值时进行初始化。最后,您不需要大括号,尽管您喜欢的编码风格可能需要使用它们:
foreach (range(0,4) as $x) $d[$x*2] = $x*3;
从字符数来看,这一行甚至比第一个解决方案还要短。
如果您想要列表推导式的惰性求值,则可以使用生成器:
$d = iterator_to_array((function() {
foreach(range(0,4) as $x) {
yield $x*2 => $x*3;
}
})());
当然,在这个模拟示例中,您立即将其转换为数组,这是毫无意义的,但是类似
$gen = function($n) {
for($x=0; $x<=$n; $x++) {
yield $x*2 => $x*3;
}
};
foreach($gen(1000000) as $k=>$v) {
echo "$k => $v\n";
}
可以迭代很多值,而无需事先将它们全部加载到内存中。
显然有有一个建议在 PHP 中实现正确的列表理解,但它已经停滞了。