Checking for a dictionary key which is a range of integers

|▌冷眼眸甩不掉的悲伤 提交于 2020-01-05 02:32:45

问题


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.

  1. 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")
    
  2. 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), where n 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!