这些Python列表推导的R等价物是什么:
[(i,j) for i,j in zip(index, Values)]
[(i,j) for i,j in enumerate(Values)]
[(i,j) for i,j in enumerate(range(10,20))] %MWE, indexing or enumerating to
%keep up with the index, there may
%be some parameter to look this up
输出示例
>>> [(i,j) for i,j in enumerate(range(10,20))]
[(0, 10), (1, 11), (2, 12), (3, 13), (4, 14), (5, 15), (6, 16), (7, 17), (8, 18), (9, 19)]
我之前已经用R中的一些技巧解决了这个问题,但不记得了,第一个想法是itertools -pkg,但我希望找到一种更惯用的做事方式。
答案 0 :(得分:33)
有关R的列表理解的一些讨论,例如here或there。 hash包甚至提供类似字典的结构。然而,正如其他人所说,很难尝试将一种语言设施映射到另一种语言设施(即使这是Comparison of programming languages实际提供的内容),而没有清楚地了解它应该用于什么。例如,我可以在R中模仿Python zip()
,如下所示:
<强>的Python 强>
In [1]: x = [1,2,3]
In [2]: y = [4,5,6]
In [3]: zip(x, y)
Out[3]: [(1, 4), (2, 5), (3, 6)]
<强> - [R 强>
> x <- 1:3
> y <- 4:6
> list(x, y) # gives a simple list
> as.list(paste(x, y)) # three tuples, as a list of characters
> mapply(list, x, y, SIMPLIFY=F) # gives a list of 3 tuples
> rbind(x, y) # gives a 2x3 matrix
可以看出,这实际上取决于你之后想要对结果做些什么。
答案 1 :(得分:31)
回答python enumerate
:
在R中,列出了一个列表(参见this answer)。因此,您只需索引键(使用names()[i]
)或值(使用[[i]]
)。
使用seq_along
(或者可以for(i in 1:length(mylist)){...}
):
> mylist <- list('a'=10,'b'=20,'c'=30)
> for (i in seq_along(mylist)){
+ print(paste(i,names(mylist)[i],mylist[[i]]))
+ }
[1] "1 a 10"
[1] "2 b 20"
[1] "3 c 30"
回答python zip
:
请参阅上述答案之一,以模仿元组列表。我倾向于使用BondedDust的答案中显示的数据框:
> x <- 1:3
> y <- 4:6
> data.frame(x=x, y=y)
x y
1 1 4
2 2 5
3 3 6
答案 2 :(得分:5)
如果那是矩阵的Python打印表示,那么这段代码:
j <- 10:20
matrix(c(seq_along(j), j), ncol=2)
#------------
[,1] [,2]
[1,] 1 10
[2,] 2 11
[3,] 3 12
[4,] 4 13
[5,] 5 14
[6,] 6 15
[7,] 7 16
[8,] 8 17
[9,] 9 18
[10,] 10 19
[11,] 11 20
你仍然离开我们这些不是Python用户的人,关于你想要的输出的结构。您使用术语“列表”,但输出表明一组有序的元组。
鉴于@ chi的指导,我们也可能建议使用非常以R为中心的“数据帧”结构
x <- 1:3
y <- 4:6
dfrm <- data.frame(x=x, y=y)
...在列类型方面具有列表的灵活性,并且在行和列索引方面具有矩阵的访问特征。或者可以使用hhh的请求并使用默认情况下以“1”开头的10:20
向量创建j向量rownames
的隐式索引值,但可以将其更改为字符矢量从“0”开始
dfrm <- data.frame(j=10:20)
dfrm[3, ]
#[1] 12
rownames(dfrm) <- 0:10
dfrm["0",]
# [1] 10
不幸的是,粗心的人会发现dfrm [0,]不是一个快乐的调用,返回长度为0的向量。
答案 3 :(得分:2)
创建向量列表的另一个选项是使用Map函数,如@peterhurford所示:https://rdrr.io/github/peterhurford/funtools/src/R/zippers.R
> x <- 1:3
> y <- 4:6
> z <- 7:9
> Map(c, x, y, z)
[[1]]
[1] 1 4 7
[[2]]
[1] 2 5 8
[[3]]
[1] 3 6 9
答案 4 :(得分:1)
要对枚举列表(例如枚举列表)使用Python样式列表推导,一种方法是安装List-comprehension软件包LC
(2018年开发)和itertools软件包(2015年开发)。
列出R中的理解力
您可以找到LC
软件包here。
install.packages("devtools")
devtools::install_github("mailund/lc")
示例
> library(itertools); library(lc)
> lc(paste(x$index, x$value), x=as.list(enumerate(rnorm(5))), )
[[1]]
[1] "1 -0.715651978438808"
[[2]]
[1] "2 -1.35430822605807"
[[3]]
[1] "3 -0.162872340884235"
[[4]]
[1] "4 1.42909760816254"
[[5]]
[1] "5 -0.880755983937781"
编程语法还没有像Python那样简洁明了,但在功能上有效并且其帮助概述如下:
“语法如下:lc(expr,列表,谓词)其中expr是要对列表中的所有元素求值的某些表达式,其中 列表是一个或多个命名列表,这些列表由名称指定 表达式名称= list_expr,谓词在哪里 应该计算为布尔值的表达式。例如, 从列表x得到所有偶数平方的列表,我们可以写 lc(x ** 2,x = x,x %% 2 == 0)。调用lc的结果是一个列表 由expr中的表达式构造而成,用于 输入列表,其中谓词的评估结果为true。”
在上面的示例中,请注意您可以将谓词留空。
Python风格的迭代器工具和枚举
您可以在Cran here中进一步使用与Python的itertools非常相似的R的itertools
library(itertools)
描述
”用于创建迭代器的各种工具,其中许多在Python itertools模块中以函数为后继模式,而其他在函数后为后继模式 在“雪”包中。”
示例。枚举
> for (a in as.list(enumerate(rnorm(5)))) { print(paste(a$index, "index:", a$value))}
[1] "1 index: 1.63314811372568"
[1] "2 index: -0.983865948988314"
[1] "3 index: -1.27096072277818"
[1] "4 index: 0.313193212706331"
[1] "5 index: 1.25226639725357"
示例。 ZIP枚举
> for (h in as.list(izip(a=1:5, b=letters[1:5]))) { print(paste(h$a, "index:", h$b))}
[1] "1 index: a"
[1] "2 index: b"
[1] "3 index: c"
[1] "4 index: d"
[1] "5 index: e"
答案 5 :(得分:0)
# similar to python. return a list of list. Short sequences get recycled.
zip <- function(...){
all.list <- list(...)
ele.names <- names(all.list)
max.length <- max(sapply(all.list, length))
lapply(0:(max.length - 1), function(i) {
res <- lapply(all.list, function(l) l[i %% length(l) + 1])
names(res) <- ele.names
res
})
}
答案 6 :(得分:0)
zip
和enumerate
在R中实现并不困难:
#' zip(1:5,1:10)
zip <- function(...) {
mapply(list, ..., SIMPLIFY = FALSE)
}
枚举很容易用zip
来定义:
#' enumerate(l=LETTERS)
enumerate <- function(...) {
zip(ix=seq_along(..1), ...)
}
由于这些功能是适当的,因此我们可以使用...
使它们相当灵活和简洁,并利用mapply的行为,例如正确回收输入和正确命名输出。
答案 7 :(得分:0)
这可以使用两个粘贴语句来实现:
str1 <- paste(1:11, 10:20, sep=",", collapse='), (')
paste("(", str1, ")", sep = "")
输出如下:
'(1,10), (2,11), (3,12), (4,13), (5,14), (6,15), (7,16), (8,17), (9,18), (10,19), (11,20)'
答案 8 :(得分:0)
对于python,R中的“枚举”等效。将向量存储在列表中并使用索引对其进行迭代应该可以正常工作。
vect1 <- c('A', 'B', 'C')
vect2 <- c('a', 'b', 'c')
# eqiv to zip values:
idx_list <- list(vect1, vect2)
idx_vect <- c(1:length(idx_list[[1]]))
for(i in idx_vect){
x <- idx_list[[1]][i]
j <- idx_list[[2]][i]
print(c(i, x, j))
}
输出:
[1] "1" "A" "a"
[1] "2" "B" "b"
[1] "3" "C" "c"
R“列表”是存放向量并保留索引的好库。