【问题标题】:Why the variables are going out of scope in the for loop particularly while inside function为什么变量在for循环中超出范围,特别是在函数内部
【发布时间】:2016-02-22 23:10:03
【问题描述】:

我期待一个字典列表,但字典深度未知。它可以是list of dict of dict 或list 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 已转换为string,dict 中的list 也转换为string。但其他人不是,为什么? 当我调试代码时,我可以看到,它正在更改为else 中的string,但在最终输出中它没有反映为什么? 还有一件事pycharmshadows else 部分告诉我们,局部变量key and keyv1 没有被使用.. 为什么?

【问题讨论】:

  • 为什么还要这样做?如果你有非 ascii 字符,使用 str 不会很好地结束,就像 idjaw 指出的那样,你永远不会真正使用 key 或 key1
  • @PadraicCunningham:我认为recursion 是找出字典中depth 的唯一方法。这就是我遵循这种方式的原因。如果您有其他解决方法,请指导,
  • @RasmiRanjanNayak,如果有点过于复杂,递归很好,我会更关心在 unicode 上调用 str,你到底想做什么?

标签: python dictionary unicode pycharm


【解决方案1】:

从哪里开始......

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

2) 在你的 else-if 你试图改变keyv1,keyv1[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?​​p>

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

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)

【讨论】:

    【解决方案2】:

    您的主要问题是,当您重复时,您会丢弃结果。你有

    abc(keyv1)

    但您不会将返回的结果保存在任何地方。您必须使用它来更改原始字典。更改 key 和 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'}]}]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-13
      • 2011-09-07
      • 2010-11-11
      • 2018-12-17
      相关资源
      最近更新 更多