【问题标题】:How to filter a dict of list in python?如何在python中过滤列表的字典?
【发布时间】:2013-01-08 06:03:30
【问题描述】:

我有一个由 django 构建的博客应用程序,如果有新评论,我想通知博主,所以这就是我所做的

class Blog(models.Model):
     lastview = models.DateTimeField('self last view date')

class Comment(models.Model):
     blog = models.ForeignKey(Blog)
     timestamp = models.DateTimeField('comment date')

user_blog_list = Blog.Objects.filter(author = request.user)
user_blog_com = {}

for blog in user_blog_list:
      user_blog_com [blog] =list(Comment.objects.filter(blog = blog ))

现在user_blog_com 是dict 的样子

{
  (Blog: blogname1):[(Comment:comment1),(Comment:comment2)],
  (Blog: blogname2):[(Comment:comment1),(Comment:comment2)],
}

接下来我需要将每个评论的时间戳与博客的 lastview 进行比较,以确定该评论是否被博主查看,但我不知道如何。

我想要的是一张类似的光盘

{
  (Blog: blogname):[(Comment:unviewed_comment),(Comment:unviewed_comment)],
}

请帮忙!!!

我试试这个

user_blog_com = {}

for blog in user_blog_list:
      user_blog_com [blog] =list(Comment.objects.filter(blog = blog ,timestamp > blog.lastview ))

 get an error: non-keyword arg after keyword arg

【问题讨论】:

  • 在查询Comments 时为什么不这样做?
  • dicts 没有顺序...你可能想看看ordereddict
  • 你的意思是 user_blog_com [blog] =list(Comment.objects.filter(blog = blog, timestamp > blog.lastview )) ?
  • @chenliang 我相信你是从错误的方向来解决这个问题的。您正在执行许多可以通过单个 ORM 查询来实现的迂回处理。
  • 是的,我做到了,我得到它的工作方式:user_blog_com [blog] =list(Comment.objects.filter(blog = blog ,timestamp__ge = blog.lastview))

标签: python django list dictionary


【解决方案1】:

我还没有测试过,但是下面应该会为您提供每个博客的新 cmets 列表。

from django.db.models import F

comments = Comment.objects.filter(
        blog__author=request.user
    ).filter(
        timestamp__gte=F('blog__lastview')
    ).select_related('blog').order_by('blog')

F() Expressions 允许您逐行引用数据库中的值。除此之外,您只是要求所有新的 cmets timestamp__gte=blog__lastview,其中当前用户是作者。我们使用select_related,因此您无需其他查询即可访问blog 实例的详细信息,而order_by('blog') 则使您有一些订单。

如果您必须在字典中包含这些信息(我想知道为什么会这样..),那么您可以执行以下操作:

from collections import defaultdict
d = defaultdict(list)
for comment in comments:
    d[comment.blog.name].append(comment)

比您尝试构建它的方式更具可读性和表现力。

【讨论】:

    【解决方案2】:

    试试这个

    ret_dict = {}
    for k, v in user_blog_com.items():
        # Check comments timestamp is smaller than lastview.
        ret_dict[k] = [x for x in v if x.timestamp <= k.lastview]
    
    print ret_dict
    

    这可能会对你有所帮助。

    【讨论】:

    • 或者:ret_dict = {k:[x for x in v if x.timestamp &lt;= k.lastview] for k, v in user_blog_com.items()} 在 python 2.7+ 中
    猜你喜欢
    • 2022-01-23
    • 2017-10-29
    • 1970-01-01
    • 2023-03-23
    • 2018-04-30
    • 2022-01-25
    • 2021-11-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多