Python:将解压缩的元组用作(dict)键的通用方法

时间:2018-07-26 09:28:34

标签: python python-3.x dictionary iterable-unpacking

在python中,我们可以解压缩函数参数,以便获得单个元素:

def printAll(*args):
    print(args, *args)  # packed and unpacked version respectively
printAll(1)  # (1,) 1
printAll(1, 2)  # (1, 2) 1 2

但是,我想定义一个函数(除其他外)使用某些参数访问某个容器(例如dict)。 该字典是预定义的,无法修改! 我遇到了以下麻烦:

# e.g. d is a dict with
#    d[1] = 1 <- key is scalar
#    d[1, 2] = 3 <- key is tuple
def accessDict(name, *args):
    print('Hello', name)
    d[args]
    # d[*args] what I'd need, but it's invalid syntax
accessDict('foo', 1)  # should give 1 but gives KeyError because args is (1,) not 1
accessDict('foo', 1, 2)  # should give 3

一种替代方法是添加:

if len(args) == 1:
    return d[args[0]]

但是我觉得应该有一种更优雅的方式来做到这一点...

3 个答案:

答案 0 :(得分:4)

正确的方法是使密钥具有一致性,例如:

d = {(1,): 1, (1, 2): 3}

如果不能,但是需要对该字典进行许多操作,则可以对其进行预处理:

d = {1: 1, (1, 2): 3}
dd = { (k if isinstance(k, tuple) else (k,)): v for k, v in d.items() }

如果只需要使用几次,则可以坚持最初的建议:

def accessDict(name, *args):
    print('Hello', name)
    d[args if len(args) > 1 else d[args[0]]]

答案 1 :(得分:1)

首先,如SergeBallesta's solution中所述,您应该考虑将字典键重新定义为一致的元组。

否则,您可以使用dict.get来使用后备广告:

d = {1: 1, (1, 2): 3}

def accessDict(name, *args):
    return d.get(args[0], d.get(args))

accessDict('foo', 1)     # 1
accessDict('foo', 1, 2)  # 3

如果这确实是瓶颈,并且不太可能出现这种情况,则可以使用try / except

def accessDict(name, *args):
    try:
        return d[args[0]]
    except KeyError:
        return d[args]

我认为最新版本是 most Pythonic。如果它像鸭子一样嘎嘎叫,那就是鸭子。无需检查长度/类型/等。

答案 2 :(得分:-2)

首先,默认情况下,元组是所有python方法的参数。

根据您的情况,您不能将arg用作字典密钥,而字典密钥不存在。因此,如果要这样做,则需要从元组中提取每个键,并将其分配给字典。

此代码可能会对您有所帮助。

d = {1: 1, (1, 2): 3}
def accessDict(name, *args):
   print('Hello', name)


 #So simple edit is
   for a in args:
       d[a] #1, 3 


accessDict('foo', 1) 
accessDict('foo', (1, 2))