提取深层嵌套列表的名称

时间:2018-07-10 08:07:44

标签: r

假设我有一个这样的列表:

import rethinkdb as rt
import csv
import datetime as dt
import time

#EXAMPLE LOCAL IP FOR THE SAKE OF POSTING
rt.connect("0.0.0.0").repl()


date = dt.datetime.now()

updates = {'Object A':0,'Object B':0}

while True:
    for code in updates:
        prev = {}
        query = list(rt.db("test").table("table").filter(rt.row["Name"][:len(code)+1] == code + ' ').run())
        try:
            # IF TEXT FILE EXISTED ALREADY, READ THE FILE
            with open(code + '{:02d}'.format(date.year) + '{:02d}'.format(date.month) + '{:02d}'.format(date.day) + '.txt',"r+",newline='') as file:
                reader = csv.reader(file, delimiter='\t')
                writer = csv.writer(file, delimiter='\t')
                print('prev len1: '+ str(len(prev)))
                prev = {row[0]:row[1] for row in reader}

                file.truncate()

                for item in query:
                    try:
                        if item['Counter'] < prev[item['Name']]:    # THE KEYERROR THAT THE TRY BLOCK IS TRYING TO CATCH WOULD BE RAISED IN THIS LINE
                            prev[item['Name']] = prev[item['Name']] + item['Counter']
                        else:
                            prev[item['Name']] = item['Counter']
                    except KeyError:
                        prev[item['Name']] = item['Counter']

                    writer.writerow([item['Name'],prev[item['Name']]])

        except:
            # IF TEXT FILE FOR THE DAY DOESN'T EXIST, CREATE A NEW FILE
            with open(code + '{:02d}'.format(date.year) + '{:02d}'.format(date.month) + '{:02d}'.format(date.day) + '.txt',"w",newline='') as file:
                for item in query:
                    writer = csv.writer(file,delimiter='\t')
                    writer.writerow([item['Name'],item['Counter']])

        file.close()

    print('Updated...')
    time.sleep(30)

我想获取m <- list('a' = list('b' = c(1, 2), 'c' = 3, 'b1' = 4)) 的名称并保持水平。

如果我愿意

m

它提供输出

names(unlist(m))

但是我只想要类似的名字

"a.b1" "a.b2" "a.c"  "a.b1"

如何获得?

对于大的嵌套列表,"a.b" "a.c" "a.b1" 也很昂贵。没有unlist()并且有更快的方式可以做到这一点吗?

unlist()

2 个答案:

答案 0 :(得分:4)

您可以通过递归地仅提取列表中每个向量的第一个元素并获取该结构的名称来到达那里:

names(rapply(m, function(x) head(x, 1)))
#[1] "a.b"  "a.c"  "a.b1"

下面是输入列表更复杂的示例:

m <- list(a=list(b=c(1, 2), c=3, b1=list(x=1, y=2:4)), x=list(a=1,b=2), c=4:8)
str(m)
# List of 3
# $ a:List of 3
# ..$ b : num [1:2] 1 2
# ..$ c : num 3
# ..$ b1:List of 2
# .. ..$ x: num 1
# .. ..$ y: int [1:3] 2 3 4
# $ x:List of 2
# ..$ a: num 1
# ..$ b: num 2
# $ c: int [1:5] 4 5 6 7 8

names(rapply(m, function(x) head(x, 1)))
#[1] "a.b"    "a.c"    "a.b1.x" "a.b1.y" "x.a"    "x.b"    "c" 

对于OP的第二个输入,将产生:

p <- list('a' = list('z' = c(1, 2), 'g' = list('i' = 2, 'j' = 3)), 'd' = list('k' = c(4, 5)))
names(rapply(p, function(x) head(x, 1)))
#[1] "a.z"   "a.g.i" "a.g.j" "d.k"

答案 1 :(得分:0)

您的列表m具有这种结构。

> str(m)
List of 1
 $ a:List of 3
  ..$ b : num [1:2] 1 2
  ..$ c : num 3
  ..$ b1: num 4

如您所见,您想将顶级列表的名称与第二级列表的名称连接起来。您可以通过paste0(names(m), ".", names(m[[1]][1:3]))或仅通过以下方式实现此目标:

> paste0(names(m), ".", names(m[[1]][]))
[1] "a.b"  "a.c"  "a.b1"