问题
I'm building a dictionary of manufacturers. It would look something like this:
mfgs = {17491: 'DS', 6543: 'AC'}
In this scenario, I need to represent a range of integers that all refer to the same manufacturer. (e.g. 1 - 99 are all manufactured by DC)
I've seen that you can create a dictionary key in which a range is represented.
mfgs = {17491: 'DS', 6543: 'AC', (1,99): 'DC'}
Later on, I will have an integer grabbed from an external file. Depending upon the value encountered, I will log the appropriate manufacturer into another file.
I am unclear on how to check for the presence of a valid key/value pair (whether a number or a range of numbers) and log "Unknown" if neither is found without building an expanding if/then that accounts for keys defined in the dictionary.
It seems like try/except is appropriate, but if 21 is encountered, mfg[21] fails and it shouldn't.
回答1:
You need more than just a simple hashmap (i.e. dictionary) lookup. Hashmaps lookup particular keys, not whether a key is in range of any of the existing keys.
You have two simple options.
If you know the ranges ahead of time, convert the integer into a range before looking it up:
def range_from_id(manufacturer_id): if 1 <= manufacturer_id <= 99: return (1, 99) return manufacturer_id manufacturer_id = ... from file ... manufacturer_range = range_from_id(manufacturer_id) manufacturer = mfgs.get(manufacturer_range, "Unknown")
If you don't, then keep track of the ranges in a separate dictionary, and loop through all possible values:
mfgs = {17491: 'DS', ...} mfg_ranges = {(1, 99): 'DC', ...} def lookup_manufacturer(manufacturer_id): # direct look-up: if manufacturer_id in mfgs: return mfgs[manufacturer_id] # range look-up: for (start, end), mfg in mfg_ranges.items(): if start <= manufacturer_id <= end: return mfg return "Unknown"
If speed is important, note that this option will take
O(n)
, wheren
is the number of ranges you have. A more proper way to do it would be using binary trees, as amit answered here. This would require using a 3rd party library like bintrees.
回答2:
I found a way to do this. Please note that i is there because we're in a for-loop iterating through found items. mfgs is a dictionary pre-populated.
try:
drivers_list[i]['mfg'] = mfgs[mfg] # Attempt to store in dictionary
except:
if 1 <= mfg <= 31: # On exception, see if it's the known mfg.
drivers_list[i]['mfg'] = 'The known manufacturer' # Between 1 and 31
else:
drivers_list[i]['mfg'] = 'Unknown' # otherwise post unknown
来源:https://stackoverflow.com/questions/33393714/checking-for-a-dictionary-key-which-is-a-range-of-integers