2

我正在尝试过滤表中的数组对象。这是我过滤的一个案例,它工作得很好。

tags = ["school", "hollywood"]
tagsLambda =  lambda post: (post["tags"].contains(tags[0])) | (post["tags"].contains(tags[1]))
d = r.db("test").table("posts").filter(
    tagsLambda
).run()

但是,我的问题是我正在手动执行 lambda 操作,而不是我想tagsLambda过滤所有tags. 我该怎么做?

4

2 回答 2

3

我认为你应该能够做这样的事情:

tags = ["school", "hollywood"]
r.db("test").table("posts").filter(
  lambda post: post["tags"].contains(lambda tag:
    r.expr(tags).contains(tag)
  )
).run(conn)

http://rethinkdb.com/api/python/contains/

于 2015-02-09T12:42:03.753 回答
1
tags = ["school", "hollywood"]
tagsLambda =  lambda post: ( 
eval('|'.join(
           [r'(post["tags"].contains("' + tag + '"))' for tag in tags]
    ))
)
d = r.db("test").table("posts").filter(tagsLambda).run()  

[ r'post["tags"].contains("' + tag + '")' for tag in tags ]是一个列表理解。(post["tags"].contains("school"))它为标签中的每个标签构建一个字符串列表。该'|'.join操作从带有“|”的字符串列表中构建一个字符串 介于两者之间(post["tags"].contains("school")) | (post["tags"].contains("hollywood"))。eval 评估整个字符串。

上面的代码可以使用reduceas 来简化

tags = ["school", "hollywood"]
tagsLambda =  lambda post:
    reduce(lambda x,y: x | y, [ post["tags"].contains(tag) for tag in tags])

d = r.db("test").table("posts").filter(tagsLambda).run()  

对于 Python 3,必须导入 'functools' 才能使用reduce并替换reducefunctools.reduce.

第二个 lambda 可以用函数替换。

import operator as op
reduce(op.or_, [ post["tags"].contains(tag) for tag in tags])  

用户生成器以获得更好的结果。

reduce(op.or_, ( post["tags"].contains(tag) for tag in tags))  
于 2015-02-09T12:44:05.530 回答