有没有办法将 Python 转换为 R?
Is there a way to convert Python to R?
嘿,我正在尝试将我的 python 代码转换为 R,但似乎无法弄清楚递归的最后一部分。如果任何有两种语言经验的人可以提供帮助,那就太好了!
def robber(nums):
if len(nums) == 0: return 0
elif len(nums) <= 2: return max(nums)
else:
A = [nums[0], max(nums[0:2])]
for i in range(2, len(nums)):
A.append(max(A[i-1], A[i-2] + nums[i]))
return A[-1]
上面是 Python 版本,下面是我迄今为止尝试转换为 R
robbing <- function(nums) {
if (length(nums) == 0){
result <- 0
}
else if(length(nums) <= 2){
result <- max(nums)
}
else{
a <- list(nums[0], max(nums(0:2)))
for (i in range(2, length(nums))){
result <- max(a[i-1], a[i-2] + nums[i])
}
}
#result <- a[-1]
}
我建议您可以将 result
更改为 return()
并在函数外重命名对象 a
,并在结束时将 len
更改为 length()
函数。
a <- list(nums[0], max(nums(0:2)))
robbing <- function(nums) {
if (length(nums) == 0){
return(0)
}
else if(length(nums) <= 2){
return(max(nums))
}
else{
for (i in range(2, length(nums))){
return(max(a[i-1], a[i-2] + nums[i]))
}
}
return(a[length(a)])
}
你有几个问题。
- 您正在对向量进行零索引。 R 是 1 索引的(
y
的第一个元素是 y[1]
而不是 y[0]
。
- R 中的范围(python 中的切片)包含。例如:
0:2 = c(0, 1, 2)
而 python 是右排他的 0:2 = [0, 1]
.
- R 使用减号元素来“移除”向量的元素,而 Python 使用这些减号元素来逆序提取。例如:
y[-1] = y[2:length(y)]
在 R.
- R 的
range
功能与Python 的range
功能不同。 R
中的等效项是 seq
或 a:b
(例如 3:n
)。不是说它是右包含的,而 pythons 是右独占的!
- 您没有像在 python 中那样将中间结果存储在
a
中。您需要在 运行-time 时执行此操作
最后一个:R 函数默认 return 最后一个计算。所以没有必要显式使用return
。这不是每个人的问题,而是可以使代码看起来更干净(或在某些情况下不太干净)的东西。因此,解决您问题的一种选择是:
robber <- function(nums){
n <- length(nums) # <= Only compute length **once** =>
if(n == 0)
0 # <= Returned because no more code is run after this =>
else if(n <= 2)
max(nums) # <= Returned because no more code is run after this =>
else{
a <- numeric(n) # <= pre-allocate our vector =>
a[1:2] <- cummax(nums[1:2]) # <= Cummax instead of c(nums[1], max(nums[1:2])) =>
for(i in 3:n){ # <= Note that we start at 3, because of R's 1-indexing =>
a[i] <- max(a[i - 1], a[i - 2] + nums[i])
}
a[n]
}
}
注意 3 件事:
- 我使用 R 向量是 1 索引的,因此我的范围从
3
开始。
- 我预先分配了我的
a
向量(这里使用 numeric(n)
)。 R 向量扩展是 慢 而 python 列表在时间复杂度上是恒定的。因此,在所有情况下都建议采用预分配方式。
- 我提取我的长度一次并将它存储在一个变量中。
n <- length(nums)
。本质上没有必要多次评估这个,建议将这些中间结果存储在一个变量中。这适用于 R、Python 等任何语言,甚至 C++ 等编译语言(而对于后者,在许多情况下,编译器足够聪明,不会重新计算结果)。
最后我尽可能使用 cummax
。我觉得有一种优化的方法可以使用矢量化几乎立即获得结果,但我不太明白。
我会避免使用列表。因为附加列表很慢。 (特别是在 R 中!- Vector 要好得多。但是如果我们像我在这里向您展示的那样使用变量,我们不需要任何序列和索引)。
你不需要建立一个列表。
你需要记住的只是以前的
和 res.
的先前值
def robber(nums, res=0, prev=0, preprev=0): # local vars predefined here
for x in nums:
prev, preprev = res, prev
res = max(prev, preprev + x)
return res
此 python 函数与您提供的功能相同。 (试试吧!)。
在 R 中这将是:
robber <- function(nums, res=0, prev=0, preprev=0) {
for (x in nums) {
preprev <- prev
prev <- res # correct order important!
res <- max(prev, preprev + x)
}
res
}
将局部变量定义放入参数列表中在 R 中节省了 3 行代码,因此我做到了。
嘿,我正在尝试将我的 python 代码转换为 R,但似乎无法弄清楚递归的最后一部分。如果任何有两种语言经验的人可以提供帮助,那就太好了!
def robber(nums):
if len(nums) == 0: return 0
elif len(nums) <= 2: return max(nums)
else:
A = [nums[0], max(nums[0:2])]
for i in range(2, len(nums)):
A.append(max(A[i-1], A[i-2] + nums[i]))
return A[-1]
上面是 Python 版本,下面是我迄今为止尝试转换为 R
robbing <- function(nums) {
if (length(nums) == 0){
result <- 0
}
else if(length(nums) <= 2){
result <- max(nums)
}
else{
a <- list(nums[0], max(nums(0:2)))
for (i in range(2, length(nums))){
result <- max(a[i-1], a[i-2] + nums[i])
}
}
#result <- a[-1]
}
我建议您可以将 result
更改为 return()
并在函数外重命名对象 a
,并在结束时将 len
更改为 length()
函数。
a <- list(nums[0], max(nums(0:2)))
robbing <- function(nums) {
if (length(nums) == 0){
return(0)
}
else if(length(nums) <= 2){
return(max(nums))
}
else{
for (i in range(2, length(nums))){
return(max(a[i-1], a[i-2] + nums[i]))
}
}
return(a[length(a)])
}
你有几个问题。
- 您正在对向量进行零索引。 R 是 1 索引的(
y
的第一个元素是y[1]
而不是y[0]
。 - R 中的范围(python 中的切片)包含。例如:
0:2 = c(0, 1, 2)
而 python 是右排他的0:2 = [0, 1]
. - R 使用减号元素来“移除”向量的元素,而 Python 使用这些减号元素来逆序提取。例如:
y[-1] = y[2:length(y)]
在 R. - R 的
range
功能与Python 的range
功能不同。R
中的等效项是seq
或a:b
(例如3:n
)。不是说它是右包含的,而 pythons 是右独占的! - 您没有像在 python 中那样将中间结果存储在
a
中。您需要在 运行-time 时执行此操作
最后一个:R 函数默认 return 最后一个计算。所以没有必要显式使用return
。这不是每个人的问题,而是可以使代码看起来更干净(或在某些情况下不太干净)的东西。因此,解决您问题的一种选择是:
robber <- function(nums){
n <- length(nums) # <= Only compute length **once** =>
if(n == 0)
0 # <= Returned because no more code is run after this =>
else if(n <= 2)
max(nums) # <= Returned because no more code is run after this =>
else{
a <- numeric(n) # <= pre-allocate our vector =>
a[1:2] <- cummax(nums[1:2]) # <= Cummax instead of c(nums[1], max(nums[1:2])) =>
for(i in 3:n){ # <= Note that we start at 3, because of R's 1-indexing =>
a[i] <- max(a[i - 1], a[i - 2] + nums[i])
}
a[n]
}
}
注意 3 件事:
- 我使用 R 向量是 1 索引的,因此我的范围从
3
开始。 - 我预先分配了我的
a
向量(这里使用numeric(n)
)。 R 向量扩展是 慢 而 python 列表在时间复杂度上是恒定的。因此,在所有情况下都建议采用预分配方式。 - 我提取我的长度一次并将它存储在一个变量中。
n <- length(nums)
。本质上没有必要多次评估这个,建议将这些中间结果存储在一个变量中。这适用于 R、Python 等任何语言,甚至 C++ 等编译语言(而对于后者,在许多情况下,编译器足够聪明,不会重新计算结果)。
最后我尽可能使用 cummax
。我觉得有一种优化的方法可以使用矢量化几乎立即获得结果,但我不太明白。
我会避免使用列表。因为附加列表很慢。 (特别是在 R 中!- Vector 要好得多。但是如果我们像我在这里向您展示的那样使用变量,我们不需要任何序列和索引)。 你不需要建立一个列表。 你需要记住的只是以前的 和 res.
的先前值def robber(nums, res=0, prev=0, preprev=0): # local vars predefined here
for x in nums:
prev, preprev = res, prev
res = max(prev, preprev + x)
return res
此 python 函数与您提供的功能相同。 (试试吧!)。
在 R 中这将是:
robber <- function(nums, res=0, prev=0, preprev=0) {
for (x in nums) {
preprev <- prev
prev <- res # correct order important!
res <- max(prev, preprev + x)
}
res
}
将局部变量定义放入参数列表中在 R 中节省了 3 行代码,因此我做到了。