【问题标题】:Python: Converting a queryset in a list of tuplesPython:在元组列表中转换查询集
【发布时间】:2017-02-03 18:42:32
【问题描述】:
class User(models.Model):
    email = models.EmailField()
    name = models.CharField()

如何获取用户的电子邮件和名称作为元组列表?我目前的解决方案是这样的:

result = []
for user in User.objects.all():
    result.append((user.email, user.name))

【问题讨论】:

  • 如果你有多个键/值对,你只需要 x 和 y 怎么办?
  • for 循环仍然可以在 python 中使用。并非所有东西都必须是单线
  • 为了缩短代码使用列表理解而不是 for 循环。

标签: python django performance


【解决方案1】:

如果这是一个 django ORM 查询集(或它的结果),您可以只使用 values_list 方法而不是 values。这将完全满足您的需求。

【讨论】:

    【解决方案2】:

    假设queryset 应该看起来像这样,'x''y' 作为字符串键:

    >>> queryset = [{'x':'1', 'y':'a'}, {'x':'2', 'y':'b'}]
    >>> result = [(q['x'], q['y']) for q in queryset]
    >>> result
    [('1', 'a'), ('2', 'b')]
    >>> # or if x and y are actually the correct names/vars for the keys
    ... result = [(q[x], q[y]) for q in queryset]
    

    【讨论】:

    • 谢谢!到底是什么在搜索
    【解决方案3】:

    如果您可以有多个键并且只需要某些键值,则可以使用 itemgetter 和 map 传递您要提取的键:

    from operator import itemgetter
    result = list(map(itemgetter("x", "y"), queryset)))
    

    【讨论】:

      【解决方案4】:

      你可以使用dict.values():

      queryset = [{x:'1',y:'a'}, {x:'2',y:'b'}]
      result = []
      
      for i in queryset:
          result.append(tuple(i.values()))
      

      或者在一行中:

      result = [tuple(i.values()) for i in queryset]
      

      如果您希望它们按特定顺序排列:

      result = [(i[x], i[y]) for i in queryset]

      【讨论】:

      • i.values() 不一定会在 'y' 值之前返回 'x' 值,因此您有时可以给出 [('a', '1'), ('b', '2')](或类似的组合),而不是 [('1', 'a'), ('2', 'b')]
      • 在您编辑的答案中,((i[y], i[x])) 是错误的顺序。但无论如何,您在编辑中所做的与 OP 在他的问题中的相同
      【解决方案5】:

      使用列表理解和dict.values()

      >>> queryset = [{'x': '1', 'y': 'a'}, {'x': '2', 'y': 'b'}]
      >>> result = [tuple(v.values()) for v in queryset]
      >>> result
          [('1', 'a'), ('2', 'b')]
      

      更新

      正如@aneroid 合理地提到的那样,由于dict 对象没有排序,所以代码 sn-p 可以在tuple 中返回不同的顺序

      所以因为我不想添加重复的解决方案。有一种选择,不是那么优雅,而且可能效率不高,可以使用OrderedDict

      >>> from collections import OrderedDict
      >>> queryset = [{'x': '1', 'y': 'a'}, {'x': '2', 'y': 'b'}]
      >>> order = ('x', 'y')
      >>> result = [tuple(OrderedDict((k, v[k]) for k in myorder).values()) for v in queryset]
      >>> result
          [('1', 'a'), ('2', 'b')]
      

      但我个人认为@PadraicCunningham 的solution 是这里最优雅的。

      【讨论】:

      • v.values() 不一定会在 'y' 值之前返回 'x' 值,因此您有时可以给出 [('a', '1'), ('b', '2')](或类似的组合),而不是 [('1', 'a'), ('2', 'b')]
      【解决方案6】:

      your_tuple = [(x.get('attrA'), x.get('attrB')) for x in queryset.values()]

      【讨论】:

      • querysetlist 而不是 dict
      • [(x, y) for x, y in queryset.items()] 会为您提供与 list(queryset.items()) 相同的值,这是键/值而不是值。
      【解决方案7】:

      为此使用values_list

      result = User.objects.all().values_list("email", "name")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-08-31
        • 1970-01-01
        • 2015-08-16
        • 2010-12-25
        • 2015-12-21
        • 1970-01-01
        • 2012-10-01
        • 2011-07-27
        相关资源
        最近更新 更多