【问题标题】:Is there a shorthand for querying a dictionary in python?是否有在 python 中查询字典的简写?
【发布时间】:2011-07-27 18:13:48
【问题描述】:

这是我要执行的查询类型,用伪代码编写:

select blob from blobs where blob['color'] == 'red' having maximum(blob['size'])

显然,我可以在 python 中这样写:

redBlobs = [];

for blob in blobs:
    if blob['color'] == 'red':
        redBlobs.append('blob')

largestBlob = None

for redBlob in redBlobs:
    if largestBlob == None or redBlob['size'] > largestBlob['size']:
        largestBlob = redBlob

return largestBlob

但我怀疑有一种更清洁的方法。我是 python 新手,所以我仍然非常迫切地接近它。

编辑:

这是我在查看其他一些关于 SO 的问题后提出的解决方案:

max([blob for blob in blobs if blob['color'] == 'red'], key = lambda b: b['size'])

想必还有更好的办法。

【问题讨论】:

  • 编辑的解决方案比较好,它只有一个严重的问题(除了缺少关闭]导致的语法错误):列表推导导致Python创建一个整体在开始评估之前所有红色 blob 对象的新列表。使用生成器表达式,它在 O(1) 空间中运行(假设 max 使用 O(1) 空间,这几乎可以肯定)。
  • 您的解决方案几乎是完美的,除了三点:首先它缺少一个 ],其次它构建了一个对生成器无用的列表,第三您可以使用比 lambda 更快的 operator.itemgetter

标签: python syntactic-sugar


【解决方案1】:

以下给出最大的 blob

编辑:在没有红色斑点时捕获异常

import operator
try:
    largestBlob = max((blob for blob in blobs if blob['color'] == 'red'),key=operator.itemgetter('size'))
except ValueError:
    largestBlob = None

【讨论】:

  • +1 完美。并且为了记录,operator.attrgetter 相当于 itemgetter 如果它是一个对象属性而不是一个 dict 条目。
【解决方案2】:

这样就可以了:

redBlobs = filter(lambda b: b['color'] == 'red', blobs)
largestBlob = max(redBlobs, key=lambda b: b['size'])

【讨论】:

    【解决方案3】:

    PiotrLegnica 的答案将返回最大 blob 的大小,而不是最大 blob 本身。要获得最大的 blob,请使用 max 的可选“key”参数:

    largestBlob = max((blob for blob in blobs if blob['color'] == 'red'), key=operator.itemgetter('size'))
    

    【讨论】:

    • 确实,必须是blob for blob in blobs if ...。修复它并使用key=operator.itemgetter('size'),它就完美了。
    • @delnan:我稍微简化了一些事情:blob 不是字典,而是一个对象,因此您可以通过blob.size 访问“大小”。 operator.itemgetter('size') 还能用吗?
    • @Eric:不会,但operator.attrgetter('size') 会。
    • @delnan:感谢您的修复。那将教我下次测试我的代码。 :)
    【解决方案4】:

    如果我是你,我会使用大小作为键进行排序,并使用生成器表达式进行过滤,获取该列表的第一个元素:

    largestBlob = sorted((blob for blob in blobs if blob['color'] == 'red'), key=lambda x: -x['size'])[0]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-16
      • 2019-01-23
      • 2015-02-04
      • 1970-01-01
      • 2022-12-10
      • 2018-03-04
      相关资源
      最近更新 更多