我希望我的字典不区分大小写.
我有这个示例代码:
text = "practice changing the color"
words = {'color': 'colour',
'practice': 'practise'}
def replace(words,text):
keys = words.keys()
for i in keys:
text= text.replace(i ,words[i])
return text
text = replace(words,text)
print text
Run Code Online (Sandbox Code Playgroud)
输出=练习改变颜色
我想要另一个字符串,"practice changing the Color"(Color以一个大写字母开头)也给出相同的输出.
我相信有一种通用的方法可以转换为小写,
mydictionary[key.lower()]但我不知道如何最好地将它集成到我现有的代码中.(如果这是一个合理,简单的方法,无论如何).
m00*_*000 52
在目前已批准的答案不适合工作,很多情况下,所以它不能被用来作为一个下拉dict更换.获得适当dict替换的一些棘手要点:
以下应该会更好:
class CaseInsensitiveDict(dict):
@classmethod
def _k(cls, key):
return key.lower() if isinstance(key, basestring) else key
def __init__(self, *args, **kwargs):
super(CaseInsensitiveDict, self).__init__(*args, **kwargs)
self._convert_keys()
def __getitem__(self, key):
return super(CaseInsensitiveDict, self).__getitem__(self.__class__._k(key))
def __setitem__(self, key, value):
super(CaseInsensitiveDict, self).__setitem__(self.__class__._k(key), value)
def __delitem__(self, key):
return super(CaseInsensitiveDict, self).__delitem__(self.__class__._k(key))
def __contains__(self, key):
return super(CaseInsensitiveDict, self).__contains__(self.__class__._k(key))
def has_key(self, key):
return super(CaseInsensitiveDict, self).has_key(self.__class__._k(key))
def pop(self, key, *args, **kwargs):
return super(CaseInsensitiveDict, self).pop(self.__class__._k(key), *args, **kwargs)
def get(self, key, *args, **kwargs):
return super(CaseInsensitiveDict, self).get(self.__class__._k(key), *args, **kwargs)
def setdefault(self, key, *args, **kwargs):
return super(CaseInsensitiveDict, self).setdefault(self.__class__._k(key), *args, **kwargs)
def update(self, E={}, **F):
super(CaseInsensitiveDict, self).update(self.__class__(E))
super(CaseInsensitiveDict, self).update(self.__class__(**F))
def _convert_keys(self):
for k in list(self.keys()):
v = super(CaseInsensitiveDict, self).pop(k)
self.__setitem__(k, v)
Run Code Online (Sandbox Code Playgroud)
san*_*lto 47
仅供记录.我在Requests上发现了一个很棒的命令:
https://github.com/kennethreitz/requests/blob/v1.2.3/requests/structures.py#L37
jkp*_*jkp 40
如果我理解正确并且你想要一种以非区分大小写的方式键入字典的方法,一种方法是子类化dict并重载setter/getter:
class CaseInsensitiveDict(dict):
def __setitem__(self, key, value):
super(CaseInsensitiveDict, self).__setitem__(key.lower(), value)
def __getitem__(self, key):
return super(CaseInsensitiveDict, self).__getitem__(key.lower())
Run Code Online (Sandbox Code Playgroud)
ple*_*con 11
在我的特定实例中,我需要一个不区分大小写的查找,但是,我不想修改密钥的原始大小写.例如:
>>> d = {}
>>> d['MyConfig'] = 'value'
>>> d['myconfig'] = 'new_value'
>>> d
{'MyConfig': 'new_value'}
Run Code Online (Sandbox Code Playgroud)
您可以看到字典仍然具有原始密钥,但是它不受大小写的影响.这是一个简单的解决方案:
class CaseInsensitiveKey(object):
def __init__(self, key):
self.key = key
def __hash__(self):
return hash(self.key.lower())
def __eq__(self, other):
return self.key.lower() == other.key.lower()
def __str__(self):
return self.key
Run Code Online (Sandbox Code Playgroud)
在字典中获取和设置条目都需要__hash__和__eq__覆盖.这是创建键,如果它们不区分大小写,则散列到字典中的相同位置.
现在要么创建一个自定义词典,使用提供的键初始化CaseInsensitiveKey:
class CaseInsensitiveDict(dict):
def __setitem__(self, key, value):
key = CaseInsensitiveKey(key)
super(CaseInsensitiveDict, self).__setitem__(key, value)
def __getitem__(self, key):
key = CaseInsensitiveKey(key)
return super(CaseInsensitiveDict, self).__getitem__(key)
Run Code Online (Sandbox Code Playgroud)
或者只是确保在使用字典时始终将CaseInsensitiveKey的实例作为键传递.
ins*_*get 10
您会考虑使用string.lower()输入并使用完全小写字典吗?这是一个hacky解决方案,但它的工作原理
我已经修改了pleasemorebacon的简单但很好的解决方案(谢谢!),使其更加紧凑、独立,并进行了少量更新以允许构建{'a':1, 'B':2}和支持__contains__协议。最后,由于CaseInsensitiveDict.Key预计将字符串(还有什么可以区分大小写或没有),这是一个好主意,派生Key从类str的话,那是可能的,例如,转储CaseInsensitiveDict与json.dumps开箱。
# caseinsensitivedict.py
class CaseInsensitiveDict(dict):
class Key(str):
def __init__(self, key):
str.__init__(key)
def __hash__(self):
return hash(self.lower())
def __eq__(self, other):
return self.lower() == other.lower()
def __init__(self, data=None):
super(CaseInsensitiveDict, self).__init__()
if data is None:
data = {}
for key, val in data.items():
self[key] = val
def __contains__(self, key):
key = self.Key(key)
return super(CaseInsensitiveDict, self).__contains__(key)
def __setitem__(self, key, value):
key = self.Key(key)
super(CaseInsensitiveDict, self).__setitem__(key, value)
def __getitem__(self, key):
key = self.Key(key)
return super(CaseInsensitiveDict, self).__getitem__(key)
Run Code Online (Sandbox Code Playgroud)
这是一个基本的测试脚本,适合那些喜欢检查实际情况的人:
# test_CaseInsensitiveDict.py
import json
import unittest
from caseinsensitivedict import *
class Key(unittest.TestCase):
def setUp(self):
self.Key = CaseInsensitiveDict.Key
self.lower = self.Key('a')
self.upper = self.Key('A')
def test_eq(self):
self.assertEqual(self.lower, self.upper)
def test_hash(self):
self.assertEqual(hash(self.lower), hash(self.upper))
def test_str(self):
self.assertEqual(str(self.lower), 'a')
self.assertEqual(str(self.upper), 'A')
class Dict(unittest.TestCase):
def setUp(self):
self.Dict = CaseInsensitiveDict
self.d1 = self.Dict()
self.d2 = self.Dict()
self.d1['a'] = 1
self.d1['B'] = 2
self.d2['A'] = 1
self.d2['b'] = 2
def test_contains(self):
self.assertIn('B', self.d1)
d = self.Dict({'a':1, 'B':2})
self.assertIn('b', d)
def test_init(self):
d = self.Dict()
self.assertFalse(d)
d = self.Dict({'a':1, 'B':2})
self.assertTrue(d)
def test_items(self):
self.assertDictEqual(self.d1, self.d2)
self.assertEqual(
[v for v in self.d1.items()],
[v for v in self.d2.items()])
def test_json_dumps(self):
s = json.dumps(self.d1)
self.assertIn('a', s)
self.assertIn('B', s)
def test_keys(self):
self.assertEqual(self.d1.keys(), self.d2.keys())
def test_values(self):
self.assertEqual(
[v for v in self.d1.values()],
[v for v in self.d2.values()])
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
46567 次 |
| 最近记录: |