从另一个字典中创建一个包含特定键值对的Python字典。

8

我有一些代码看起来像这样:

d = {'foo': True, 'bar': 42, 'baz': '!'}

a = {'foo': d['foo'], 'bar': d['bar']}
b = {'foo': d['foo'], 'baz': d['baz']}
c = {'bar': d['bar'], 'baz': d['baz']}

肯定有更好的方式来表达这个意思。我读过文档,希望字典的copy方法能接受要包含在新字典中的键:

# I'd hoped that something like this would work...
a = d.copy('foo', 'bar')
b = d.copy('foo', 'baz')
c = d.copy('bar', 'baz')

我可以编写一个函数来实现此目的:

我可以为此编写一个函数:

copydict = lambda dct, *keys: {key: dct[key] for key in keys}

a = copydict(d, 'foo', 'bar')
b = copydict(d, 'foo', 'baz')
c = copydict(d, 'bar', 'baz')

有没有更好的解决方案呢?

为什么不使用列表(或集合)来存储a、b、c?当需要时,您可以在d中查找该值。 - maxy
我实际上正在将abc传递给Django的urlencode函数(就像urllib.urlencode一样,它接受一个字典)。 - davidchambers
@BlaXpirit:你应该写一个只包含“不。”的答案(用HTML注释填充到最小尺寸),这样我们就可以疯狂地投票支持它。 - Chris Morgan
如果您感兴趣,我发布了一个相关问题,关于如何比复制更好:https://dev59.com/P2DVa4cB1Zd3GeqPeY3M - Marcin
3个回答

6

我认为这个问题中的函数是最佳解决方案。

当然,有人可能会发布一些惯用代码,但我相信它不会更好/更快。遍历列表并通过键从字典中获取项目与其速度无关。

一个建议是从keys参数中删除星号。参数解包会增加不必要的开销。只需将这些键作为元组传递即可。


3
我唯一想做的改进就是使用真正的函数定义,而不是lambda表达式:
def copy_dict(d, *keys):
    """Make a copy of only the `keys` from dictionary `d`."""
    return {key: d[key] for key in keys}

处理缺失的键可能很有用,但在Python 2中,您不能很好地将可选关键字参数与*args混合使用,因此您可能需要转而使用元组参数:

def copy_dict(d, keys, default=None):
    """Make a copy of only the `keys` from dictionary `d`.

    Use `default` if a key is missing.

    """
    return {key: d.get(key, default) for key in keys}

0
正如@BlaXpirit所指出的那样,从速度和可读性方面来看,这个解决方案可能不会比你的更好,但你可以尝试像这样做:
>>> from operator import itemgetter
>>> d = {'foo': True, 'bar': 42, 'baz': '!'}
>>> keys = ['foo', 'bar']
>>> dict(zip(keys, itemgetter(*keys)(d)))
{'bar': 42, 'foo': True}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接