使用键开始字符访问 Python dict 值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17106819/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Accessing Python dict values with the key start characters
提问by Roman Rdgz
I was wondering: would it be possible to access dict values with uncomplete keys (as long as there are not more than one entry for a given string)? For example:
我想知道:是否可以使用不完整的键访问 dict 值(只要给定字符串的条目不超过一个)?例如:
my_dict = {'name': 'Klauss', 'age': 26, 'Date of birth': '15th july'}
print my_dict['Date']
>> '15th july'
Is this possible? How could it be done?
这可能吗?怎么可能呢?
采纳答案by Ashwini Chaudhary
You can't do such directly with dict[keyword], you've to iterate through the dict and match each key against the keyword and return the corresponding value if the keyword is found.
This is going to be an O(N)operation.
您不能直接使用dict[keyword],您必须遍历字典并将每个键与关键字匹配,如果找到关键字,则返回相应的值。这将是一个O(N)手术。
>>> my_dict = {'name': 'Klauss', 'age': 26, 'Date of birth': '15th july'}
>>> next(v for k,v in my_dict.items() if 'Date' in k)
'15th july'
To get all such values use a list comprehension:
要获得所有这些值,请使用列表理解:
>>> [ v for k,v in my_dict.items() if 'Date' in k]
['15th july']
use str.startswithif you want only those values whose keys starts with 'Date':
使用str.startswith,如果你只希望它的键与“日期”开始的值:
>>> next( v for k,v in my_dict.items() if k.startswith('Date'))
'15th july'
>>> [ v for k,v in my_dict.items() if k.startswith('Date')]
['15th july']
回答by Martijn Pieters
Sure it is possible:
当然有可能:
print next(val for key, val in my_dict.iteritems() if key.startswith('Date'))
but this incurs a full scan through the dictionary. It only finds the firstsuch matching key (where 'first' is arbitrary) and raises StopIterationinstead of KeyErrorif no keys match.
但这会导致对字典进行全面扫描。它只找到第一个这样匹配的键(其中 'first' 是任意的)并且在没有键匹配时引发StopIteration而不是KeyError。
To get closer to what you are thinking of, it's better to write this as a function:
为了更接近你的想法,最好把它写成一个函数:
def value_by_key_prefix(d, partial):
matches = [val for key, val in d.iteritems() if key.startswith(partial)]
if not matches:
raise KeyError(partial)
if len(matches) > 1:
raise ValueError('{} matches more than one key'.format(partial))
return matches[0]
回答by Elazar
You are not suggesting a coherent API:
你不是在建议一个连贯的 API:
- What should be the result of
my_dict['']? You don't have a one-to-one mapping. - How is it supposed to be extended to types other than
str?
- 结果应该是什么
my_dict['']?您没有一对一的映射。 - 它应该如何扩展到
str?以外的类型?
Another reason you can't have it directly, even for strings and assuming you always return a list, is because Python's dictis implemented using a hash table, and it will map xyand xzto unrelated cells in the table.
另外一个原因,你不能把它直接,甚至串并假设你总是返回一个列表,是因为Python的dict使用哈希表来实现,这将映射xy并xz在表中无关的细胞。
So, going the other way: such a lookup to would mean going for a slower implementation of dict, (which doesn't make sense, optimizing for an uncommon use) or being as slower as a full scan - which you may as well write it by hand, as it is not thatcommon to be worth a dedicated convenience method.
因此,换一种方式:这样的查找将意味着对 , 的较慢实现dict(这没有意义,针对不常见的使用进行优化)或与完整扫描一样慢 - 你也可以写它通过手,因为它不是该共同值得专用简便方法。
回答by Ali SAID OMAR
not the best solution, can be improved (overide getitem)
不是最好的解决方案,可以改进(覆盖getitem)
class mydict(dict):
def __getitem__(self, value):
keys = [k for k in self.keys() if value in k]
key = keys[0] if keys else None
return self.get(key)
my_dict = mydict({'name': 'Klauss', 'age': 26, 'Date of birth': '15th july'})
print(my_dict['Date'])# returns 15th july
回答by formiaczek
There's a nice and clever implementation of a 'fuzzy' dictionary in pywinauto - this might be perfect for what you need here.
pywinauto 中有一个很好且聪明的“模糊”字典实现 - 这可能非常适合您在这里需要的东西。
https://code.google.com/p/pywinauto/source/browse/pywinauto/fuzzydict.py
https://code.google.com/p/pywinauto/source/browse/pywinauto/fuzzydict.py
and docs here: http://pywinauto.googlecode.com/hg/pywinauto/docs/code/pywinauto.fuzzydict.html
和这里的文档:http: //pywinauto.googlecode.com/hg/pywinauto/docs/code/pywinauto.fuzzydict.html
(edit: although if you specifically want to match from the beginning of the key, you might need to replace SequenceMatcher logic with your custom code)
(编辑:虽然如果你特别想从键的开头匹配,你可能需要用你的自定义代码替换 SequenceMatcher 逻辑)
回答by saurabh
>>> my_dict = {'name': 'Klauss', 'age': 26, 'Date of birth': '15th july'}
>>> next(v for k,v in my_dict.items() if 'Date' in k)
'15th july'
>>> [ v for k,v in my_dict.items() if 'Date' in k]
['15th july']
>>> next( v for k,v in my_dict.items() if k.startswith('Date'))
'15th july'
>>> [ v for k,v in my_dict.items() if k.startswith('Date')]
['15th july']
if i use the above given method i am getting StopIteration exception
如果我使用上面给出的方法,我会收到 StopIteration 异常
回答by Yogesh Kate
You can use the built-in filter function to filter dictionaries, lists, etc. based on specific conditions.
您可以使用内置的过滤器功能,根据特定条件过滤字典、列表等。
filtered_dict = dict(filter(lambda item: "Date" in item[0], my_dict.items()))
The advantage is that you can use it for different data structures.
优点是您可以将它用于不同的数据结构。

