我可以将字典的值/条目和键传递给函数吗
我正在写一个函数,打算用字典的键和值作为参数。比如说:
testDict={'x':2,'xS':4}
def newFunct(key,testDict['key']):
newvalue=key+str(testDict['key'])
return newValue
for key in testDict:
newValue=newFunct(key,testDict[key])
print newValue
但是当我在输入分号后按回车时,出现了一个语法错误:无效的语法。我猜这可能是在告诉我,不能以那种方式传递字典的值。大概我可以定义一个新变量
for key in testDict:
xdixt=testDict[key]
newValue=newFunct(key,xdixt)
然后用这个新变量来定义函数。
不过我希望能找到一些我还没想到的技巧。我在网上搜索了一下,发现有提到解包字典的内容,但那似乎没什么用。
这Python的东西真的很酷。我之所以会有这个问题,是因为我想用我存储在字典里的某些值来创建一个新目录。根据我从Stephan的回答中读到的内容,我在想如何把我学到的信息进行概括。我的目录名称有五个不同的部分,每个部分都是处理myDict中的值的结果。创建目录名称的表达式变得太复杂了,我觉得不容易阅读。所以我想知道能不能用同样的方法把这些部分放到一个列表里,然后在创建目录名称的时候解包它们,结果真的成功了!
def createDirectory(myKey,**myDict):
pathList=[]
pathList.append(myDict['subKey1'])
pathList.append(myDict['subKey2'].lstrip('0'))
pathList.append(myDict['subKey3'])
etc
myPath=os.path.join(*myList)
os.makedirs(myPath)
return(myPath)
4 个回答
你为什么不直接这样做呢:
[k + str(v) for k, v in test_dict.iteritems()]
或者对于Python 3来说:
[k + str(v) for k, v in test_dict.items()]
补充说明
def f(k, v):
print(k, v) # or do something much more complicated
for k, v in testDict.items():
f(k, v)
这就是你想要的吗?
def func(**kwargs):
for key, value in kwargs.items():
pass # Do something
func(**myDict) # Call func with the given dict as key/value parameters
(想了解更多关于关键字参数的内容,可以查看文档。在myDict
中的键必须是字符串。)
编辑: 你更新了你的问题,增加了以下内容:
我认为在myDict前面的**符号是告诉函数要期待一个字典,并且要解包键(第一个*)和值(第二个*)。
这个理解是不对的。要明白发生了什么,你需要考虑以下几点:
- 一个函数可以有多个正式参数(在这个例子中是
a
和b
):
def f1(a, b): pass
- 我们可以向这样的函数传递位置参数(就像在大多数其他语言中一样):
f1(2, 3)
- 我们也可以传递关键字参数:
f1(a=2, b=3)
- 我们还可以混合使用这两种参数,但位置参数必须放在前面:
f1(2, b=3) f1(a=2, 3) # SyntaxError: non-keyword arg after keyword arg
- 有一种方法可以让函数接受任意数量的位置参数,这些参数可以作为一个元组(在这个例子中是
args
)访问:
def f2(*args): assert isinstance(args, tuple)
- 现在我们可以用单独指定的参数调用
f2
,或者使用一个列表,列表的内容需要先解包,用的语法类似于*args
的写法:
f2(2, 3) f2(*[2, 3])
- 同样,函数也可以接受任意数量的关键字参数:
def f3(**kwargs): pass
- 注意,
f3
并不要求一个类型为dict
的单一参数。这是它期望的调用方式:
f3(a=2, b=3) f3(**{'a': 2, 'b': 3})
- 所有传给
f3
的参数必须有名字:
f3(2, 3) # TypeError: f3() takes exactly 0 arguments (2 given)
把这些内容结合起来,记住位置参数必须在前,我们可能会有:
>>> def f4(a, b, *args, **kwargs):
... print('%r, %r' % (args, kwargs))
...
>>> f4(2, 3)
(), {}
>>> f4(2, 3, 4, 5)
(4, 5), {}
>>> f4(2, 3, x=4, y=5)
(), {'y': 5, 'x': 4}
>>> f4(2, 3, 4, 5, x=6, y=7)
(4, 5), {'y': 7, 'x': 6}
>>> f4(2, *[3, 4, 5], **{'x': 6, 'y': 7})
(4, 5), {'y': 7, 'x': 6}
特别注意以下两个错误:
>>> f4(2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f4() takes at least 2 arguments (1 given)
>>> f4(2, 3, a=4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f4() got multiple values for keyword argument 'a'
第二个错误应该能帮助你解释这种行为:
>>> f4(**{'foo': 0, 'a': 2, 'b': 3, 'c': 4})
(), {'c': 4, 'foo': 0}
我不太明白为什么要用kwargs,这样做其实简单多了。你说你刚学Python,我觉得你需要先掌握一些Python的基础知识。
def newFunct(key,testDict['key']):
应该是:
def newFunct(key, val):
在第二个参数上没有必要使用任何特殊的语法来表示它来自一个字典。它只是一个参数,你只不过是把字典中的一个值传递给它而已。
而且,一旦这个值进入函数,也没有必要以特殊的方式对待它。此时它只是一个普通的值。这意味着:
newvalue=key+str(testDict[key])
现在可以简单写成:
newvalue=key+str(val)
所以当你这样调用它的时候(就像你做的那样):
newValue=newFunct(key,testDict[key])
testDict[key] 会得到 'key' 对应的值,这个值在函数里就变成了 "val"。
另外一种方法,如果你觉得有必要(这只是个好知道的知识),你可以这样定义函数:
def newFunct(key, testDict):
同样,第二个参数只是一个参数,所以我们用相同的语法,但现在我们期望它是一个字典,所以我们应该像使用字典一样来用它:
newvalue=key+str(testDict[key])
(注意:在这种情况下,不要给 'key' 加引号。我们指的是名为 'key' 的变量,而不是一个叫 'key' 的键)。当你调用这个函数时,它看起来是这样的:
newValue=newFunct(key,testDict)
所以和第一种情况不同,这次你传递的是整个字典的引用,而不是仅仅从字典中传递一个变量。
希望这对你有帮助。