Python 将混合嵌套列表转换为线性dict

Python 将混合嵌套列表转换为线性dict,python,list,dictionary,tuples,Python,List,Dictionary,Tuples,给定嵌套列表:[1,(1,2),[3,4],{5:6}],编写一个程序,将这些元素的元素作为键,并将这些元素的位置作为值 我的代码:(阅读评论) 是的 电话: print code([1, (1, 2), {3: 4}, [5, 6]]) 输出: {(1, 2): 1, 1: 0, 3: 2, 4: 2, 5: 3, 6: 3} {1: 0, (1, 2): 1, 3: 2, 4: 2, 5: 2, 6: 3, 7: 3, 8: 3} # ^ ^ ^

给定嵌套列表:
[1,(1,2),[3,4],{5:6}]
,编写一个程序,将这些元素的元素作为键,并将这些元素的位置作为值

我的代码:(阅读评论)

是的

电话:

print code([1, (1, 2), {3: 4}, [5, 6]])
输出:

{(1, 2): 1, 1: 0, 3: 2, 4: 2, 5: 3, 6: 3}
  {1: 0, (1, 2): 1, 3: 2, 4: 2, 5: 2, 6: 3, 7: 3, 8: 3}  
 #    ^          ^     ^     ^     ^     ^     ^     ^ 
 #        index in outer list             
我是Python学习者,我编写此代码时假设从列表中获取的键是唯一的,例如,
[1,2,[1,2]]
是无效输入

[问题]

  • 我只是想知道:如何进一步改进我的代码,使其变得既短又快
  • 我从“一个快速入门的Python”中学到,应该避免使用
    isinstance()
    。那么,有没有其他方法来编写此代码

  • 你能建议我如何改进任意嵌套和混合的代码吗

    #   0     1            2        3         <-- index
       [1, (1, 2), {3: [4, 5]}, [{6: 7} , 8]]
    
    我可以处理嵌套在两个级别,但嵌套在任何级别对我来说都是不可能的,请建议一个技巧。一个建议就足够了,但应该是Pythonic。
    (第三个问题是我发布此问题的主要问题)

  • 编辑:

    正如上文所指出的:

    您想如何处理
    [1,{1:2}]
    <根据当前规则,代码>1应同时映射到
    0
    1

    为了简单起见,我假设这个输入是无效的<代码>“假设从列表中获取的密钥是唯一的”

    应避免使用isinstance()。那么,有没有其他方法来编写此代码

    除了课本练习之外,我很少在数据中看到如此任意的异质性,因此我同意建议您尽可能避免
    isinstance
    。因此,一般的答案是:如果你发现自己在处理疯狂的结构,那么给你的代码设计得很糟糕,你应该修复它。换句话说,对
    code()
    的调用所需的输出是
    {(1,2):1,1:0,3:2,4:2,5:3,6:3}
    对于不需要更多代码(至少不需要像
    code()
    本身那样复杂的代码)的值,您可以做什么

    将这个问题转化为C术语:您需要多久处理一次指向联合的指针数组?几乎从来没有,当你这样做的时候,这是一件痛苦的事情,因为工会总是需要随身携带一个类型指示器,这样你才能确保访问合适的工会成员

    我们应该捕捉每一个可能的异常,否则代码错误

    这是错误的;您希望代码出错,因为这是发现bug的好方法。以下:

    错误永远不应该悄无声息地过去
    除非明确沉默

    您永远不应该捕获不知道如何处理的异常,并且打印错误消息很少算作正确处理异常。一个更全面的解决这一常见错误的方法

    应避免使用isinstance()。那么,有没有其他方法来编写此代码

    除了课本练习之外,我很少在数据中看到如此任意的异质性,因此我同意建议您尽可能避免
    isinstance
    。因此,一般的答案是:如果你发现自己在处理疯狂的结构,那么给你的代码设计得很糟糕,你应该修复它。换句话说,对
    code()
    的调用所需的输出是
    {(1,2):1,1:0,3:2,4:2,5:3,6:3}
    对于不需要更多代码(至少不需要像
    code()
    本身那样复杂的代码)的值,您可以做什么

    将这个问题转化为C术语:您需要多久处理一次指向联合的指针数组?几乎从来没有,当你这样做的时候,这是一件痛苦的事情,因为工会总是需要随身携带一个类型指示器,这样你才能确保访问合适的工会成员

    我们应该捕捉每一个可能的异常,否则代码错误

    这是错误的;您希望代码出错,因为这是发现bug的好方法。以下:

    错误永远不应该悄无声息地过去
    除非明确沉默


    您永远不应该捕获不知道如何处理的异常,并且打印错误消息很少算作正确处理异常。一个更全面的解决这一常见错误的方法

    我听不懂你写的东西:

    我编写此代码时假设从列表中获取的密钥是唯一的,例如,
    [1,2,[1,2]]
    是无效输入

    但您的“有效”输入是:

    [1,(1,2),{3:4}[5,6]]

    重复数字“1”的地方

    无论如何,我想回答你的问题。我将在if..else语句中编写一个递归方法(该方法将处理任意嵌套项)。例如,类似这样的事情:

    def foo(a):
        x = {}
        for i,b in enumerate(a):
            if isinstance(b,list):
                for k in b:
                    x[k]=i
            elif isinstance(b,dict):
                for k in b.items():
                    x[k[0]]=i
                    x[k[1]]=i
            elif isinstance(b,set):
                for k in b:
                    x[k]=i
            elif isinstance(b,tuple):
                for k in b:
                    x[k]=i
            else:
                x[b]=i
        return x
    
    foo([1,(2,3),{4,5},[6,7]])
    {1: 0, 2: 1, 3: 1, 4: 2, 5: 2, 6: 3, 7: 3}
    

    虽然我无法回答您关于isinstance函数的速度有多快,但恐怕这是检测类型的唯一方法。

    我不明白您写的一些内容:

    bigList = [1, (1, 2), {(3,9): [4, 5]}, [{6: 7} , 8]]
    linear_dict = dict()
    
    def nestedList(l, index = None, break_tuple = False):
        for count, item in enumerate(l):
            if type(item) is list:
                nestedList(item, index if index else count)
            elif type(item) is dict:
                nestedList(item.iteritems(), index if index else count, True)
            elif type(item) is tuple and break_tuple:
                nestedList(list(item), index)
            else:
                linear_dict[item] = index if index else count
    
    nestedList(bigList)
    print linear_dict
    
    {(1, 2): 1, 1: 0, 4: 2, 5: 2, 6: 3, 7: 3, 8: 3, (3, 9): 2}
    
    我编写此代码时假设从列表中获取的密钥是唯一的,例如,
    [1,2,[1,2]]
    是无效输入

    但您的“有效”输入是:

    [1,(1,2),{3:4}[5,6]]

    重复数字“1”的地方

    无论如何,我想回答你的问题。我将在if..else语句中编写一个递归方法(该方法将处理任意嵌套项)。例如,类似这样的事情:

    def foo(a):
        x = {}
        for i,b in enumerate(a):
            if isinstance(b,list):
                for k in b:
                    x[k]=i
            elif isinstance(b,dict):
                for k in b.items():
                    x[k[0]]=i
                    x[k[1]]=i
            elif isinstance(b,set):
                for k in b:
                    x[k]=i
            elif isinstance(b,tuple):
                for k in b:
                    x[k]=i
            else:
                x[b]=i
        return x
    
    foo([1,(2,3),{4,5},[6,7]])
    {1: 0, 2: 1, 3: 1, 4: 2, 5: 2, 6: 3, 7: 3}
    
    虽然我无法回答您isinstance函数的速度有多快,但恐怕这是检测类型的唯一方法

    bigList = [1, (1, 2), {(3,9): [4, 5]}, [{6: 7} , 8]]
    linear_dict = dict()
    
    def nestedList(l, index = None, break_tuple = False):
        for count, item in enumerate(l):
            if type(item) is list:
                nestedList(item, index if index else count)
            elif type(item) is dict:
                nestedList(item.iteritems(), index if index else count, True)
            elif type(item) is tuple and break_tuple:
                nestedList(list(item), index)
            else:
                linear_dict[item] = index if index else count
    
    nestedList(bigList)
    print linear_dict
    
    {(1, 2): 1, 1: 0, 4: 2, 5: 2, 6: 3, 7: 3, 8: 3, (3, 9): 2}
    
    这更像是递归的问题,而不是列表、元组和字典的问题

    关于
    isinstance()
    type()
    ,请阅读以下内容:

  • 尽管如此,这里提到的东西并不适用于你的问题,因为正如msw所提到的,它更像是一个教科书上的问题。除此之外,链接中的答案还包含一些好的建议

    巴斯