假设 d 是一个字典
d={' a ':1,'b ':2}
如果我们这样给予
d.has_key(' a ')
True
但这是错误的
d.has_key('a')
False
所以我试过这样
d.has_key('\sa\s')
False
那么如何在不删除空格的情况下找到具有空格的dict键
提前致谢
假设 d 是一个字典
d={' a ':1,'b ':2}
如果我们这样给予
d.has_key(' a ')
True
但这是错误的
d.has_key('a')
False
所以我试过这样
d.has_key('\sa\s')
False
那么如何在不删除空格的情况下找到具有空格的dict键
提前致谢
您将不得不删除它们:
d = {' a ':1,'b ':2}
key = 'a'
print any(key == k.strip() for k in d.iterkeys())
印刷True
要获取值,您可以使用以下方法:
def get_stripped(d, key):
return next((v for k,v in d.iteritems() if key == k.strip()), None)
print get_stripped(d, 'a') # prints 1
print get_stripped(d, 'c') # prints None
d = {' a ': 1, ' a': 2}
如果和 ,这将只返回一个任意值key = 'a'
。
如果你经常需要它,你可以子类化dict
:
class D(dict):
def __init__(self, *args, **kwargs):
super(D, self).__init__(*args, **kwargs)
self._skeys = dict((k.strip(), v) for k, v in self.iteritems())
def __setitem__(self, key, val):
super(D, self).__setitem__(key, val)
self._skeys[key.strip()] = key
def __getitem__(self, key):
try:
return dict.__getitem__(self, key)
except KeyError:
return self[self._skeys[key]]
def __contains__(self, key):
return (dict.__contains__(self, key) or key in self._skeys)
用法:
d = D({'a':1, 'b':2})
d[' c '] = 3
print 'c' in d # True
print d['c'] # 3
这个类工作正常,如果key_n.strip() != key_m.strip()
是 True 对于任何n != m
您可以使用此生成器表达式:'a' in (item.strip() for item in d.keys())
>>> d={' a ':1, 'b ':2}
>>> 'a' in (item.strip() for item in d.keys())
True
>>> 'b' in (item.strip() for item in d.keys())
True
>>> 'c' in (item.strip() for item in d.keys())
False
>>> d
>>> {' a ': 1, 'b ': 2}
编辑
要访问该值,您可以:
>>> for key, value in d.iteritems():
if key.strip()=='a':
print value
1
或者,单行版本:
>>> [value for key, value in d.iteritems() if key.strip() == 'a'][0]
1
>>> [value for key, value in d.iteritems() if key.strip() == 'b'][0]
2
基本上,[value for key, value in d.iteritems() if key.strip() == 'b']
将返回一个值列表并[0]
用于选择第一个值。如果您有几个类似的键,例如:
>>> d = {'a':1, ' a':2, ' a ':3}
然后你可以这样做:
>>> values = [value for key, value in d.iteritems() if key.strip() == 'a']
>>> len(values)
3
>>> values[0]
1
>>> values[1]
2
>>> values[2]
3
如果您需要测试很多,我建议您创建一个剥离值的字典。
>>> d={' a ':1,'b ':2}
>>> t = dict( (pair[0].strip(), pair) for pair in d.iteritems())
>>> print t.has_key('a')
True
>>> print t['a']
(' a ', 1)
d = {' a':'b',' c ':'c','b ':'b'}
key = ' a'
[d[l] for l in d.iterkeys() if l.strip() == key.strip()]
['b']
>>>d = {' a ':1, 'b ':2}
>>>dd = dict((l.strip(), v) for l, v in d.iteritems())
>>>dd
{'a':1, 'b':2}
>>>'a' in dd
True
>>>d['a']
1
我认为@astynax 的答案中显示的概念 - 派生字典子类 - 是在正确的轨道上但是它不完整......可能是因为提供一个完整的字典子类可能需要做很多工作,因为有很多相互关联的方法将需要被覆盖。
避免这种情况的捷径是从UserDict.DictMixin
类派生一个子类,而不是dict
. 优点是它将必须写入的方法数量减少到最少四个。还可以通过实施几个附加的优化来获得更高的效率。
这是一个完整的工作示例,它的行为几乎与字典对象完全一样,除了需要忽略键周围的任何空白。除了可能在删除键时,性能应该几乎与标准字典一样好,尽管它确实使用更多内存。
import UserDict
class WhiteOut(UserDict.DictMixin):
""" Mapping object with white space insensitive keys """
def __init__(self, *args, **kwargs):
self._dict = dict(*args, **kwargs)
self._skeys = dict((k.strip(), v) for k, v in self._dict.iteritems())
def __getitem__(self, key):
try:
return self._dict.__getitem__(key)
except KeyError:
return self._skeys.__getitem__(key.strip())
def __setitem__(self, key, val):
self._dict.__setitem__(key, val)
self._skeys.__setitem__(key.strip(), val)
def __delitem__(self, key):
try:
self._dict.__delitem__(key)
except KeyError:
stripped_key = key.strip()
try:
self._skeys.__delitem__(stripped_key)
except KeyError:
raise
else: # delete item corresponding to stripped_key in _dict
for akey in self._dict:
if akey.strip() == stripped_key:
self._dict.__delitem__(akey)
return
def keys(self):
return self._dict.keys()
def __iter__(self):
return iter(self._dict)
def __contains__(self, key):
return self._skeys.__contains__(key.strip())
if __name__ == '__main__':
wo = WhiteOut({'a':1, ' b':2})
wo[' c '] = 3
print 'c' in wo # True
print wo['c'] # 3
print 'has_key:'
print wo.has_key(' c ')
print wo.has_key('c')
print wo['c '] # 3
print 'wo.keys():', wo.keys()
wokeys = [k for k in wo]
print 'wo keys via iteration:', wokeys
wo.pop("b")
print 'wo.keys() after pop("b"):', wo.keys()
try:
wo.pop('not there')
except KeyError:
pass
else:
print "wo.pop('not there') didn't raise an exception as it should have"