【问题标题】:How to get a tuple of arbitrary values from a dict?如何从字典中获取任意值的元组?
【发布时间】:2013-04-03 19:51:20
【问题描述】:

如何从匿名字典中获取任意值的元组?

def func():
    return dict(one=1, two=2, three=3)

# How can the following 2 lines be rewritten as a single line,
# eliminating the dict_ variable?
dict_ = func()
(one, three) = (dict_['one'], dict_['three'])

【问题讨论】:

    标签: python dictionary key tuples


    【解决方案1】:

    中间变量可能比这个单行更可取(更易读):

    >>> (one,three) = (lambda d:(d['one'],d['three']))(func())
    

    (实际上除了将中间值移动到一个动态生成的函数中之外什么都不做)

    【讨论】:

    • 同意;我的和你的都比必要的更丑。
    • 谢谢。请注意,我并没有要求首选方式,只是要求可能的替代方案。只有这样我才能做出风格选择。到目前为止,我同意中间变量比提供的 3 个备选方案更清楚。到目前为止,在 3 种替代方案中,我最喜欢你的。
    【解决方案2】:

    循环 func() 结果?

    one, three = [v for k, v in sorted(func().iteritems()) if k in {'one', 'three'}]
    

    如果您使用的是 Python 3,请将 .iteritems() 替换为 .items()

    演示:

    >>> def func():
    ...     return dict(one=1, two=2, three=3)
    ... 
    >>> one, three = [v for k,v in sorted(func().iteritems()) if k in {'one', 'three'}]
    >>> one, three
    (1, 3)
    

    请注意,这种方法要求您将目标列表保持在排序键顺序中,这对于应该简单明了的东西来说是一个奇怪的限制。

    这比您的版本详细得多。真的没有什么问题。

    【讨论】:

    • 这失败了,看看你的演示结果 - func()['one'] != 3.
    • @ch3ka:已修复;它需要一个排序。
    • 在一般情况下仍然失败
    • 那是因为用例实际上并不需要这些恶作剧。它适用于一般情况如果您也保持目标列表排序
    • 好吧,但这只是“有效”,因为 sorted(['one', 'three']) 是 ['one', 'three']。考虑不同的名称,它就会中断。
    【解决方案3】:

    不要那样做,在大多数情况下,中间 dict 是可以的。 可读性很重要。 如果你真的发现自己在这种情况下太频繁了,你可以使用装饰器来猴子补丁你的函数:

    In     : from functools import wraps
    
    In     : def dictgetter(func, *keys):
      .....:     @wraps(func)
      .....:     def wrapper(*args, **kwargs):
      .....:         tmp = func(*args, **kwargs)
      .....:         return [tmp[key] for key in keys]
      .....:     return wrapper
    
    In     : def func():
       ....:         return dict(one=1, two=2, three=3)
       ....: 
    
    In     : func2 = dictgetter(func, 'one', 'three')
    
    In     : one, three = func2()
    
    In     : one
    Out    : 1
    
    In     : three
    Out    : 3
    

    或类似的东西。

    当然,您也可以使用monkeypatch,以便在调用时指定所需的字段,但我猜您会想要一个包含这些机制的普通函数。

    这将与上面的 def wrapper 的主体非常相似地实现,并像

    一样使用
    one, three = getfromdict(func(), 'one', 'three' )
    

    或类似的东西,但你也可以重复使用上面的整个装饰器:

    In     : two, three = dictgetter(func, 'two', 'three')()
    
    In     : two, three
    Out    : (2, 3)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-24
      • 1970-01-01
      • 2014-12-12
      • 2011-11-22
      • 1970-01-01
      相关资源
      最近更新 更多