在Python中迭代用于字符串替换的键

在Python中迭代用于字符串替换的键,python,json,mongodb,yaml,pymongo,Python,Json,Mongodb,Yaml,Pymongo,我试图通过pyMongo将YAML(单独的JSON行)插入mongoDB。我的一些键包含句点,这会导致错误bson.errors.InvalidDocument:key“job.no”不能包含“”。根据,我需要遍历我的键来替换句点,这是有意义的 我遇到的问题是我的数据很混乱。我的json包含嵌套对象层,我不知道包含句点的字符串是什么,或者它在哪里(哪个级别)。这是我的一个小样本数据 {"uuid":"94e31-02f59","project":{"name":"oasis","job.no":

我试图通过pyMongo将YAML(单独的JSON行)插入mongoDB。我的一些键包含句点,这会导致错误
bson.errors.InvalidDocument:key“job.no”不能包含“
”。根据,我需要遍历我的键来替换句点,这是有意义的

我遇到的问题是我的数据很混乱。我的json包含嵌套对象层,我不知道包含句点的字符串是什么,或者它在哪里(哪个级别)。这是我的一个小样本数据

{"uuid":"94e31-02f59","project":{"name":"oasis","job.no":215493452,"subset":"beta"},"time":1412371841024}
我有一个递归迭代JSON的函数。我尝试了一些变体,但它要么压扁我的JSON(不再嵌套对象),要么只返回第一个对象。我想保持我输入的结构

def keyCleaner(line):
    for k, v in line.iteritems():
        if isinstance(v, dict):
            keyCleaner(v)
        else:
            nK = k
            if "." in k:
                nK = k.replace(".", "_")
            return nK, v
以下是它当前返回的内容:

(u'uuid', u'94e31-02f59')
我想让它返回的是:

{"uuid":"94e31-02f59","project":{"name":"oasis","job_no":215493452,"subset":"beta"},"time":1412371841024}

但我不明白这是怎么回事。有人能帮忙吗?

这个递归解决方案怎么样?请注意,由于标准Python的递归限制,深度嵌套字典可能无法工作

#!/usr/bin/env python

# parse initial string
import json

def keyCleaner(d):
    if type(d) is dict:
        for key, value in d.iteritems():
            d[key] = keyCleaner(value)
            if '.' in key:
                d[key.replace('.', '_')] = value
                del(d[key])
        return d
    if type(d) is list:
        return map(keyCleaner, d)
    if type(d) is tuple:
        return tuple(map(keyCleaner, d))
    return d

print keyCleaner(json.loads('{"uuid":"94e31-02f59","project":{"name":"oasis","job.no":215493452,"subset":"beta"},"time":1412371841024}'))

这个递归解决方案怎么样?请注意,由于标准Python的递归限制,深度嵌套字典可能无法工作

#!/usr/bin/env python

# parse initial string
import json

def keyCleaner(d):
    if type(d) is dict:
        for key, value in d.iteritems():
            d[key] = keyCleaner(value)
            if '.' in key:
                d[key.replace('.', '_')] = value
                del(d[key])
        return d
    if type(d) is list:
        return map(keyCleaner, d)
    if type(d) is tuple:
        return tuple(map(keyCleaner, d))
    return d

print keyCleaner(json.loads('{"uuid":"94e31-02f59","project":{"name":"oasis","job.no":215493452,"subset":"beta"},"time":1412371841024}'))

这个递归解决方案怎么样?请注意,由于标准Python的递归限制,深度嵌套字典可能无法工作

#!/usr/bin/env python

# parse initial string
import json

def keyCleaner(d):
    if type(d) is dict:
        for key, value in d.iteritems():
            d[key] = keyCleaner(value)
            if '.' in key:
                d[key.replace('.', '_')] = value
                del(d[key])
        return d
    if type(d) is list:
        return map(keyCleaner, d)
    if type(d) is tuple:
        return tuple(map(keyCleaner, d))
    return d

print keyCleaner(json.loads('{"uuid":"94e31-02f59","project":{"name":"oasis","job.no":215493452,"subset":"beta"},"time":1412371841024}'))

这个递归解决方案怎么样?请注意,由于标准Python的递归限制,深度嵌套字典可能无法工作

#!/usr/bin/env python

# parse initial string
import json

def keyCleaner(d):
    if type(d) is dict:
        for key, value in d.iteritems():
            d[key] = keyCleaner(value)
            if '.' in key:
                d[key.replace('.', '_')] = value
                del(d[key])
        return d
    if type(d) is list:
        return map(keyCleaner, d)
    if type(d) is tuple:
        return tuple(map(keyCleaner, d))
    return d

print keyCleaner(json.loads('{"uuid":"94e31-02f59","project":{"name":"oasis","job.no":215493452,"subset":"beta"},"time":1412371841024}'))

对我来说,一个不太麻烦的解决方案(但您需要跟踪代码中的修改)是简单地将包含“.”的字典包装在python列表中,并将列表存储在mongo中,而不是存储字典(这会引发错误)

我在存储域的dict时遇到问题,即:

{"facebook.com": 2500,
"google.com" : 750,
"bing.com" : 200}
上面显示了mongo
store key'作业中的错误。no'不能包含'。
,但这可以正常工作:

[{"facebook.com": 2500,
"google.com" : 750,
"bing.com" : 200}]

对我来说,一个不太麻烦的解决方案(但您需要跟踪代码中的修改)是简单地将包含“.”的字典包装在python列表中,并将列表存储在mongo中,而不是存储字典(这会引发错误)

我在存储域的dict时遇到问题,即:

{"facebook.com": 2500,
"google.com" : 750,
"bing.com" : 200}
上面显示了mongo
store key'作业中的错误。no'不能包含'。
,但这可以正常工作:

[{"facebook.com": 2500,
"google.com" : 750,
"bing.com" : 200}]

对我来说,一个不太麻烦的解决方案(但您需要跟踪代码中的修改)是简单地将包含“.”的字典包装在python列表中,并将列表存储在mongo中,而不是存储字典(这会引发错误)

我在存储域的dict时遇到问题,即:

{"facebook.com": 2500,
"google.com" : 750,
"bing.com" : 200}
上面显示了mongo
store key'作业中的错误。no'不能包含'。
,但这可以正常工作:

[{"facebook.com": 2500,
"google.com" : 750,
"bing.com" : 200}]

对我来说,一个不太麻烦的解决方案(但您需要跟踪代码中的修改)是简单地将包含“.”的字典包装在python列表中,并将列表存储在mongo中,而不是存储字典(这会引发错误)

我在存储域的dict时遇到问题,即:

{"facebook.com": 2500,
"google.com" : 750,
"bing.com" : 200}
上面显示了mongo
store key'作业中的错误。no'不能包含'。
,但这可以正常工作:

[{"facebook.com": 2500,
"google.com" : 750,
"bing.com" : 200}]


只是一个想法,为什么不把所有东西都转换成字符串,比如
json.dumps()
,修正句点并将其改回json
json.loads()
,只是一个想法。我也有这个想法。我正在处理成百上千的行,我事先不知道要查找什么字符串。现在是“job.no”,10行后可能是“task.no”或“xx9.ze”。对我来说唯一有意义的是在键中查找句点。这只是一个想法,为什么不将所有内容转换为字符串,比如
json.dumps()
,修复句点并将其更改回json
json.loads()
,这也是一个想法。我也有这个想法。我正在处理成百上千的行,我事先不知道要查找什么字符串。现在是“job.no”,10行后可能是“task.no”或“xx9.ze”。对我来说唯一有意义的是在键中查找句点。这只是一个想法,为什么不将所有内容转换为字符串,比如
json.dumps()
,修复句点并将其更改回json
json.loads()
,这也是一个想法。我也有这个想法。我正在处理成百上千的行,我事先不知道要查找什么字符串。现在是“job.no”,10行后可能是“task.no”或“xx9.ze”。对我来说唯一有意义的是在键中查找句点。这只是一个想法,为什么不将所有内容转换为字符串,比如
json.dumps()
,修复句点并将其更改回json
json.loads()
,这也是一个想法。我也有这个想法。我正在处理成百上千的行,我事先不知道要查找什么字符串。现在是“job.no”,10行后可能是“task.no”或“xx9.ze”。对我来说唯一有意义的是在键中查找句点。这比我得到的更接近,但它看起来像是只返回嵌套数组的最后一个对象。这是输出
{u'project':(u'subset',u'beta'),u'uuid':u'94e31-02f59',u'time':1412371841024L}
。添加了更多处理。其思想是使用递归替换每个可能包含更多对象的复杂对象。它也用于散列对象(但在散列时还有更多)。太棒了。非常感谢。这比我得到的更接近,但它看起来只是返回嵌套数组的最后一个对象。这是输出
{u'project':(u'subset',u'beta'),u'uuid':u'94e31-02f59',u'time':1412371841024L}
。添加了更多处理。其思想是使用递归替换每个可能包含更多对象的复杂对象。它也被用于散列对象(但还有更多需要改进的地方)