【问题标题】:How to implement a dict key generator that generates only keys with values of type list?如何实现仅生成具有列表类型值的键的字典键生成器?
【发布时间】:2014-09-17 14:01:05
【问题描述】:

我正在尝试编写一个字典键生成器,仅当键映射的值是列表类型时才会生成键迭代器,使用递归和简单的isinstance 检查(我添加了一些打印语句我自己的利益,因为我似乎无法让这个东西运行):

def list_key_generator(inputDict):
    for key in inputDict.keys():
        if (isinstance(inputDict[key], dict)): 
            print ("Entering dict: %s " % key)
            list_key_generator(inputDict[key])
        elif (isinstance(inputDict[key], list)):
            print ("Value is a list! key, value = %s, %s" % (key, inputDict[key]))
            yield key

我一定是误解了yield(不排除其他东西),因为打印出键的递归函数完全相同:

def print_list_keys(inputDict):
    for key in inputDict.keys():
        if (isinstance(inputDict[key], list)):
            print ("Value is a list! key, value = %s, %s" % (key, inputDict[key]))
        elif (isinstance(inputDict[key], dict)): 
            print_list_keys(inputDict[key])

整个示例如下所示:

#!/usr/bin/python

def print_list_keys(inputDict):
    for key in inputDict.keys():
        if (isinstance(inputDict[key], list)):
            print ("Value is a list! key, value = %s, %s" % (key, inputDict[key]))
        elif (isinstance(inputDict[key], dict)): 
            print_list_keys(inputDict[key])

def list_key_generator(inputDict):
    for key in inputDict.keys():
        if (isinstance(inputDict[key], dict)): 
            print ("Entering dict: %s " % key)
            list_key_generator(inputDict[key])
        elif (isinstance(inputDict[key], list)):
            print ("Value is a list! key, value = %s, %s" % (key, inputDict[key]))
            yield key

def main(): 

    inputDict = { "A" : { "x" : [0,1,2] , "y" : ["one", "two"] }, "B" : { "z" : ["one"] }, "C" : [9,8,7] } 

    print("Input dict : %s " % inputDict)

    # Print list keys  
    print("print_list_keys : BEGIN")
    print_list_keys(inputDict)
    print("print_list_keys : END")

    print("list_key_generator : BEGIN")
    # Print all keys in the dict, whose values are lists.
    for leafValue in list_key_generator(inputDict):
        print (leafValue)
    print("list_key_generator : END")

if (__name__ == "__main__"):
    main()

我使用的是 Python 3.4.1,输出如下:

Input dict : {'A': {'x': [0, 1, 2], 'y': ['one', 'two']}, 'C': [9, 8, 7], 'B': {'z': ['one']}} 
print_list_keys : BEGIN
Value is a list! key, value = x, [0, 1, 2]
Value is a list! key, value = y, ['one', 'two']
Value is a list! key, value = C, [9, 8, 7]
Value is a list! key, value = z, ['one']
print_list_keys : END
list_key_generator : BEGIN
Entering dict: A 
Value is a list! key, value = C, [9, 8, 7]
C
Entering dict: B 
list_key_generator : END

【问题讨论】:

  • 你不应该在 if 的第一个分支上产生返回值吗? value = list_key_generator(inputDict[key]) 产生值

标签: python python-3.x dictionary generator


【解决方案1】:

当您递归调用您的生成器时,您实际上不会迭代它们的结果。使用yield from 委托递归调用:

yield from list_key_generator(inputDict[key])

其他提示:

  • 不要打电话给.keys();您可以通过遍历字典本身来迭代键:

    for key in inputDict:
    
  • 在 Python 中,使用 if 进行测试时,您不需要在表达式周围加上括号:

    if isinstance(inputDict[key], dict): 
    

您可以使用dict.items() 来获取键和值:

def list_key_generator(d):
    for key, value in d.items():
        if isinstance(value, dict): 
            print("Entering dict:", key)
            yield from list_key_generator(value)
        elif isinstance(value, list):
            print("Value is a list! key, value = {}, {}".format(key, value))
            yield key

【讨论】:

  • 哈!凉爽的!谢谢!实际上,我也尝试过使用yield 而不使用from,但这不起作用。
  • @tmaric:在这种情况下,您只需生成子生成器而不进行迭代。您必须执行for sub in list_key_generator(inputDict[key]): yield sub,这是您在没有yield from 语法的早期版本的Python 中必须执行的操作。
  • 也非常感谢您的提示。我注意到产生函数调用的结果迫使我在示例的一个版本中写print(*leafValue),所以我放弃了。
猜你喜欢
  • 2019-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-28
  • 2015-05-30
  • 1970-01-01
相关资源
最近更新 更多