为什么变量超出了for循环的范围,特别是在函数内部时

时间:2016-02-22 23:10:04

标签: python dictionary unicode pycharm

我期待一个词典列表,但字典深度尚不清楚。它可以是list of dict of dictlist dict of dict of dict...。但输出是unicode。所以我需要删除你的unicode并需要更改它string

json_result = [{u'NI': {u'Li': u'0', u'Receive': u'3', u'Slot': u'0002',u'PCID': u'165F', u'PCIV': u'14e4', u'LinkD': u'0','Per': u'44', u'Max': u'0', u'Pro':u'Br', u'Nic': u'3',u'Co': u'1.36', u'lis': [u'1',u'2']}}]

def abc(json_result):
    temp_res = [{}]
    for key, keyv1 in json_result.iteritems():
        if type(keyv1) is dict:
            temp_res[0][str(key)] = {}
            abc(keyv1)
            temp_res[0].update({key:keyv1})
        elif type(keyv1) is list:
            for i in xrange(len(keyv1)):
               keyv1[i] = str(keyv1[i])
               key = str(key)
        else:
            key = str(key)
            keyv1 = str(keyv1)

    return temp_res

ret = abc(json_result[0])
print ret

输出

[{'NI': {u'Slot': u'0002', u'Receive': u'3', u'lis': ['1', '2'], 'Per': u'44', u'Li': u'0', u'LinkD': u'0', u'PCIV': u'14e4', u'Co': u'1.36', u'Nic': u'3', u'Pro': u'Br', u'PCID': u'165F', u'Max': u'0'}}]

如果观察输出,则第一个键NI已转换为stringlist内的dict也会转换为string。但其他人不是,为什么? 当我调试代码时,我可以看到,它正在更改为string中的else,但在最终输出中它没有反映原因? 还有一件事pycharm shadows其他部分并告诉我们,未使用局部变量key and keyv1。为什么?

2 个答案:

答案 0 :(得分:2)

从哪里开始....

1)我不确定你的想法是什么abc(keyv1)abc有一个你忽略的返回值,所以这可能是一个问题。如果您尝试将abc设为“就地”功能,请不要这样做。它只会让你的代码更难阅读和理解。

2)在您的其他人中 - 如果您尝试更改keyv1keyv1[i] = str(keyv1[i])。不要这样做,创建一个新列表并返回。

3)在你的else子句中,你说key = str(key)但是你不在任何地方使用key。您需要将key放入返回结构中。

4)Python字典不保证字典中键的类型与用于更新字典的变量类型相同。例如,试试这个:

d = dict(one=1)
d[unicode('one')] = 'new value'
key = d.keys()[0]
print key, ':', type(key) # one : <type 'str'>

5)这不是你问题的一部分,但str(unicode_thing)并不总是有效,请尝试str(u'abcdé')。您需要明确处理该异常,或者您必须知道unicode_thing实际上是有效的ascii的先验。如果是第二种情况,那么我会问你为什么要使用unicode?

以下是一些可能有助于您入门的代码:

json_result = [{u'NI': {u'Li': u'0', u'Receive': u'3', u'Slot': u'0002',u'PCID': u'165F', u'PCIV': u'14e4', u'LinkD': u'0','Per': u'44', u'Max': u'0', u'Pro':u'Br', u'Nic': u'3',u'Co': u'1.36', u'lis': [u'1',u'2']}}]

def abc(item):
    if type(item) is list:
        return list(abc(i) for i in item)
    elif type(item) is dict:
        iteritem = item.iteritems()
        return dict((str(key), abc(value)) for (key, value) in iteritem)
    else:
        try:
            return str(item)
        except UnicodeEncodeError:
            return item
            # Or maybe do something smarter.

print abc(json_result)

答案 1 :(得分:1)

你的主要问题是,当你复发时,你会丢掉结果。

ABC(keyv1)

但是你不能将返回的结果保存在任何地方。您必须使用它来更改原始字典。改变键和keyv1并不起作用;那些是局部变量。

警告是正确的:在 else 子句中,您设置局部变量,返回到循环的顶部,然后获取这些变量的新值,丢弃您刚才的字符串值了。同样,您需要将这些内容推送到字典中 - 您正在构建的temp_res值。

我认为这些会有所帮助:

temp_res[0][str(key)] = abc(keyv1)
...
else:
    temp_res[0][str(key)] = str(keyv1)

你知道这是如何运作的吗?

输出:

[{'NI': [{'Slot': '0002', 'PCIV': '14e4', 'Co': '1.36', 'Receive': '3', 'Nic': '3', 'Pro': 'Br', 'Per': '44', 'Li': '0', 'PCID': '165F', 'LinkD': '0', 'Max': '0'}]}]