如何使用 for 循环将列表中的子值相互比较?

Posted

技术标签:

【中文标题】如何使用 for 循环将列表中的子值相互比较?【英文标题】:How Can I compare the subvalues in a list to eachother using a for-loop? 【发布时间】:2019-06-17 05:50:31 【问题描述】:

目前我有一个如下所示的列表。我想开发一个 forloop 遍历列表中的每个项目并比较该列表中的字符。一个项目中的字符永远不会超过两个。

all = [[a,z]],[[a,a]],[[e,r]],[[p,p]]....(更多类似项目)]

也写成:

[[1]]
[1] "a" "z"

[[2]]
[1] "a" "a"

[[3]] 
[1] "e" "r"

[[4]] 
[1] "p" p"

我想遍历列表中的每个元素并测试项目是否相同。我想打印匹配的项目数。例如,在这个列表中,我想要:

[[2]]
 [1] "a" "a"

 [[4]] 
 [1] "p" p"

因为“a”匹配“a”,“p”匹配“p”。我希望 for 循环返回值 2,计算匹配数。

有什么建议吗?

【问题讨论】:

还有一个:sum(sapply(lst, duplicated)) 感谢我将它添加到我的基准测试中 【参考方案1】:

sapplyuniqueN 一起使用

lst1[sapply(lst1,data.table::uniqueN)==1]
[[1]]
[1] "a" "a"

[[2]]
[1] "p" "p"

【讨论】:

欢迎回到 R 端,Python Pandas 大师! @Parfait 谢谢伙计,我会尽力提高我的 R 技能 :-) 它也适用于 dplyr::n_distinct 而不是 data.table::uniqueN,并且在我的计算机上使用 dplyr 时速度快两倍。 @Moody_Mudskipper 太棒了,谢谢你的信息:-)【参考方案2】:

我们可以使用Filter 来过滤list 的元素,方法是创建一个逻辑条件,将每个list 元素中的lengthunique 元素检查为1

out <- Filter(function(x) length(unique(x))==1, lst1)
out
#[[1]]
#[1] "a" "a"

#[[2]]
#[1] "p" "p"

length(out)
#[1] 2

或者另一种选择是

sum(sapply(lst1, function(x) do.call(identical, as.list(x))))

数据

lst1 <- list(c('a', 'z'), c('a', 'a'), c('e', 'r'), c('p', 'p'))

【讨论】:

【参考方案3】:

这里还有 3 种方法:

sum((x<-unlist(lst1))[c(T,F)]==x[c(F,T)])
#[1] 2
sum(sapply(lst1,function(x) x[1] == x[2]))
#[1] 2
sum(lengths(sapply(lst1,unique))==1)
#[1] 2

还有一个基准:

lst2 <- rep(lst1,1000)

microbenchmark::microbenchmark(
  mm1 = sum((x<-unlist(lst2))[c(T,F)]==x[c(F,T)]),
  mm2 = sum(sapply(lst2,function(x) x[1] == x[2])),
  mm3 = sum(lengths(sapply(lst2,unique))==1),
  akrun = length(Filter(function(x) length(unique(x))==1, lst2)),
  WB  = length(lst2[sapply(lst2,data.table::uniqueN)==1]),
  WB2 = length(lst2[sapply(lst2,dplyr::n_distinct)==1]),
  dd  = sum(sapply(lst2, duplicated)),
  dd2 = sum(sapply(lst2, function(x) duplicated(x)[2]))
)

# Unit: microseconds
#  expr       min        lq      mean    median        uq        max neval    cld
# mm1     146.104   156.972   284.218   160.292   164.368   9357.887   100 a     
# mm2    4141.922  4493.899  5211.921  5043.449  5550.736   8576.352   100  b    
# mm3   15911.727 17504.531 19123.916 19108.955 20324.424  26267.587   100    de 
# akrun 17991.895 19451.122 21222.071 20960.609 22765.172  29885.165   100     e 
# WB    31602.789 36288.222 39258.331 37895.967 39659.628 134526.556   100      f
# WB2   14003.624 15026.653 16783.403 15391.911 16116.695 119739.284   100   c   
# dd    14493.253 15950.668 17077.778 16792.124 17932.125  21876.323   100   cd  
# dd2   16532.970 17768.060 19172.640 18722.867 20769.075  24318.128   100    de 

【讨论】:

以上是关于如何使用 for 循环将列表中的子值相互比较?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用 for 循环的情况下将列表中的所有项目与整数进行比较

无法自动更新表格视图中的子值

如何使用JS根据组合框中的子值设置值?

Swift:如何对数组中结构的子值使用 UISearchResultsUpdating?

如何在批处理文件中的for循环中使用可变长度的子字符串?

突出显示 OBIEE 或 SQL 中父值的子值差异