Check if an item is in a nested list

后端 未结 8 1672
死守一世寂寞
死守一世寂寞 2020-11-28 12:32

in a simple list following check is trivial:

x = [1, 2, 3]

2 in x  -> True

but if it is a list of list, such as:

x = [[         


        
8条回答
  •  日久生厌
    2020-11-28 13:14

    TL;DR

    x = [0, [1, 2, 3], [2, 3, [4, 5, [6], []], [7, 8]]]
    def find_n(input_list, n):
        for el in input_list:
            if el == n or (isinstance(el, list) and find_n(el, n)):
                return True
        return False
    print(find_n(x, 6))
    

    Note that, somewhat interestingly:

    def find_n(input_list, n):
        return any([el == n or (isinstance(el, list) and find_n(el, n)) for el in input_list])
    return (find_n(x, 6))
    

    Is over 50% slower to execute.

    Original Answer(s)

    What if you have a depth greater than 2? Here's one approach to the generic case:

    x = [0, [1, 2, 3], [2, 3, [4, 5, [6], []], [7, 8]]]
    
    def flatten(input_list):
        flat_list = []
        for sublist_or_el in input_list:
            if isinstance(sublist_or_el, list):
                for sublist_or_el2 in flatten(sublist_or_el):
                    flat_list.append(sublist_or_el2)
            else:
                flat_list.append(sublist_or_el)
        return flat_list
    
    print(6 in flatten(x))
    

    Not sure about speed though, but as I said, it's one approach that may be useful to someone!

    EDIT - BETTER (FASTER) ANSWER:

    This reduces the time taken (if n is found, actually even if it is not found, about half the time actually...) by returning early. This is slightly faster than @Curt F.'s answer, and slower than creating a function that assumes a maximum depth of 2 (the accepted answer).

    x = [0, [1, 2, 3], [2, 3, [4, 5, [6], []], [7, 8]]]
    def find_n(input_list, n):
        flat_list = []
        for sublist_or_el in input_list:
            if isinstance(sublist_or_el, list):
                if find_n(sublist_or_el, n) == True:
                    return True
            elif sublist_or_el == n:
                return True
        return False
    print(find_n(x, 6))
    

    Quick timing (very hacky, sorry, busy today!):

    import time
    
    x = [0, [1, 2, 3], [2, 3, [4, 5, [6], []], [7, 8]]]
    
    def a():
        def flatten(input_list):
            flat_list = []
            for sublist_or_el in input_list:
                if isinstance(sublist_or_el, list):
                    for sublist_or_el2 in flatten(sublist_or_el):
                        flat_list.append(sublist_or_el2)
                else:
                    flat_list.append(sublist_or_el)
            return flat_list
        return (6 in flatten(x))
    
    def b():
        def find_n(input_list, n):
            flat_list = []
            for sublist_or_el in input_list:
                if isinstance(sublist_or_el, list):
                    if find_n(sublist_or_el, n) == True:
                        return True
                elif sublist_or_el == n:
                    return True
            return False
        return (find_n(x, 6))
    
    
    zz = 0
    for i in range(100000):
        start_time = time.clock()
        res = a()
        zz += time.clock() - start_time
    print(a())
    print((zz)/100, "seconds")
    
    zz = 0
    for i in range(100000):
        start_time = time.clock()
        res = b()
        zz += time.clock() - start_time
    print(b())
    print((zz)/100, "seconds")
    

提交回复
热议问题