use*_*016 57 python variables dictionary urllib
我正在使用urllib.urlencode
构建Web POST参数,但是如果存在除了它们之外的值,我只想添加一些值None
.
apple = 'green'
orange = 'orange'
params = urllib.urlencode({
'apple': apple,
'orange': orange
})
Run Code Online (Sandbox Code Playgroud)
这工作正常,但是如果我将orange
变量设为可选,我怎样才能防止它被添加到参数中?像这样的东西(伪代码):
apple = 'green'
orange = None
params = urllib.urlencode({
'apple': apple,
if orange: 'orange': orange
})
Run Code Online (Sandbox Code Playgroud)
我希望这很清楚,有谁知道如何解决这个问题?
Mar*_*ers 47
在创建初始化之后,您必须单独添加密钥dict
:
params = {'apple': apple}
if orange is not None:
params['orange'] = orange
params = urllib.urlencode(params)
Run Code Online (Sandbox Code Playgroud)
Python没有将键定义为条件的语法; 如果你已经拥有了序列中的所有内容,你可以使用dict理解:
params = urllib.urlencode({k: v for k, v in (('orange', orange), ('apple', apple)) if v is not None})
Run Code Online (Sandbox Code Playgroud)
但那不是很可读.
kin*_*all 31
为了搭载sqreept的答案,这里的子类dict
根据需要运行:
class DictNoNone(dict):
def __setitem__(self, key, value):
if key in self or value is not None:
dict.__setitem__(self, key, value)
d = DictNoNone()
d["foo"] = None
assert "foo" not in d
Run Code Online (Sandbox Code Playgroud)
这将允许将现有密钥的值更改为None
,但是分配None
给不存在的密钥是no-op.如果你想设置的项目None
,以除去从如果它已经存在的字典,你可以这样做:
def __setitem__(self, key, value):
if value is None:
if key in self:
del self[key]
else:
dict.__setitem__(self, key, value)
Run Code Online (Sandbox Code Playgroud)
值None
可以,如果你在施工过程中通过他们进去.如果您想避免这种情况,请添加一个__init__
方法来过滤它们:
def __init__(self, iterable=(), **kwargs):
for k, v in iterable:
if v is not None: self[k] = v
for k, v in kwargs.iteritems():
if v is not None: self[k] = v
Run Code Online (Sandbox Code Playgroud)
您也可以通过编写它使它成为通用的,这样您就可以在创建字典时传递所需的条件:
class DictConditional(dict):
def __init__(self, cond=lambda x: x is not None):
self.cond = cond
def __setitem__(self, key, value):
if key in self or self.cond(value):
dict.__setitem__(self, key, value)
d = DictConditional(lambda x: x != 0)
d["foo"] = 0 # should not create key
assert "foo" not in d
Run Code Online (Sandbox Code Playgroud)
kmu*_*ui2 22
我建议的一种技术是使用字典解包操作符。
apple = 'green'
orange = None
params = urllib.urlencode({
'apple': apple,
**({ 'orange': orange } if orange else {})
})
Run Code Online (Sandbox Code Playgroud)
基本上,如果orange
是None
,那么上面的字典简化为
{
'apple': apple,
**({})
}
# which results in just
{
'apple': apple,
}
Run Code Online (Sandbox Code Playgroud)
orange
if is not则相反None
:
{
'apple': apple,
**({})
}
# which results in just
{
'apple': apple,
}
Run Code Online (Sandbox Code Playgroud)
可读性是有条件地内联添加键的一个缺点。可以创建一个可以帮助解决可读性问题的函数。
{
'apple': apple,
**({ "orange": orange })
}
# which results in just
{
'apple': apple,
'orange': orange
}
Run Code Online (Sandbox Code Playgroud)
小智 13
相当古老的问题,但这里是一个替代使用更新dict与空dict什么也没做的事实.
def urlencode_func(apple, orange=None):
kwargs = locals().items()
params = dict()
for key, value in kwargs:
params.update({} if value is None else {key: value})
return urllib.urlencode(params)
Run Code Online (Sandbox Code Playgroud)
小智 11
params = urllib.urlencode({
'apple': apple,
**({'orange': orange} if orange else {}),
})
Run Code Online (Sandbox Code Playgroud)
我这样做了。希望这有帮助。
apple = 23
orange = 10
a = {
'apple' : apple,
'orange' if orange else None : orange
}
Run Code Online (Sandbox Code Playgroud)
预期输出: {'orange': 10, 'apple': 23}
虽然,如果orange = None
,那么 将有一个条目None:None
。例如考虑这个:
apple = 23
orange = None
a = {
'apple' : apple,
'orange' if orange else None : orange
}
Run Code Online (Sandbox Code Playgroud)
预期输出: {None: None, 'apple': 23}