在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]]
但是我觉得应该有一种更优雅的方式来做到这一点...
答案 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))