如何通过键列表导航字典?

时间:2018-11-07 18:34:37

标签: python python-3.x dictionary key traversal

从这样的嵌套字典开始:

$row['firstNameUsers']

当我不知道会有多少个键时,如何获取my_dict = {"North America" : { "USA" : { "Virginia" : ["Norfolk","Richmond","Charlottesville"], "New York": ["Albany"]}, "Canada" : {"Saskatchewan": ["Saskatoon"], "New Brunswick":["Moncton","Saint John"]}}} print(my_dict) North America USA Virginia ['Norfolk', 'Richmond', 'Charlottesville'] New York ['Albany'] Canada Saskatchewan ['Saskatoon'] New Brunswick ['Moncton', 'Saint John'] 之类的字符串列表并以编程方式返回嵌套对象[key1, key2]?例子:

my_dict[key1][key2]

假定键的“路径”存在,但不假定有关结构深度的任何信息。

2 个答案:

答案 0 :(得分:2)

您可以在其上扔functools.reduce

>>> from functools import reduce
>>>
>>> my_dict = {"North America" : { "USA" : { "Virginia" : ["Norfolk","Richmond","Charlottesville"], "New York": ["Albany"]}, "Canada" : {"Saskatchewan": ["Saskatoon"], "New Brunswick":["Moncton","Saint John"]}}}
>>> keys = ['North America', 'Canada']
>>> reduce(dict.get, keys, my_dict)
>>> {'New Brunswick': ['Moncton', 'Saint John'], 'Saskatchewan': ['Saskatoon']}

...或编写您自己的函数。

def nest_get(dic, keys):
    result = dic
    for k in keys:
        result = result[k]
    return result

演示:

>>> nest_get(my_dict, keys)
>>> {'New Brunswick': ['Moncton', 'Saint John'], 'Saskatchewan': ['Saskatoon']}

答案 1 :(得分:1)

使用reduce

extension CLLocationCoordinate2D {

    init?(coordinateString: String) {
        let directionIsPrefix = "NEOWS".contains(coordinateString.prefix(1))
        let pattern = directionIsPrefix
            ? "([NOEWS])\\s?(\\d{1,2})°\\s?(\\d{1,2})['′]\\s?(\\d{1,2}\\.?(\\d+)?)[\"″]"
            : "(\\d{1,2})°\\s?(\\d{1,2})['′]\\s?(\\d{1,2}\\.?(\\d+)?)[\"″]\\s?([NOEWS])"

        var latlon = [Double]()
        do {
            let regex = try NSRegularExpression(pattern: pattern)
            let matches = regex.matches(in: coordinateString, range: NSRange(coordinateString.startIndex..., in: coordinateString))
            guard matches.count == 2 else { return nil }

            for match in matches {
                let m1 = coordinateString[Range(match.range(at:1), in: coordinateString)!]
                let m2 = coordinateString[Range(match.range(at:2), in: coordinateString)!]
                let m3 = coordinateString[Range(match.range(at:3), in: coordinateString)!]
                let lastIndex = directionIsPrefix ? 4 : 5
                let m4 = coordinateString[Range(match.range(at:lastIndex), in: coordinateString)!]
                let value : Double
                if directionIsPrefix {
                    let sign = "NEO".contains(m1) ? 1.0 : -1.0
                    value = sign * (Double(m2)! + Double(m3)!/60.0 + Double(m4)!/3600.0)
                } else {
                    let sign = "NEO".contains(m4) ? 1.0 : -1.0
                    value = sign * (Double(m1)! + Double(m2)!/60.0 + Double(m3)!/3600.0)
                }
                latlon.append(value)
            }
        } catch {
            print(error)
            return nil
        }
        self.init(latitude: latlon[0], longitude: latlon[1])
    }
}

输出

from functools import reduce

my_dict = {"North America": {"USA": {"Virginia": ["Norfolk", "Richmond", "Charlottesville"], "New York": ["Albany"]},
                             "Canada": {"Saskatchewan": ["Saskatoon"], "New Brunswick": ["Moncton", "Saint John"]}}}

keys = ["North America", "USA", "Virginia"]

result = reduce(lambda x, y : x.get(y), [my_dict] + keys)
print(result)