Search code examples
pythonlistloopssettuples

Printing elements of a list and handling nested data types in Python


I am trying to print each element in this list:

l=[7, ['one', 'two', 'three'], (1, 2), 6, ('a',), {'set1', 'set2'}, 5.4, [None]]

I want the output to show this:

list [ 0 ] = 7
list [ 1 ] [ 0 ] = one
list [ 1 ] [ 1 ] = two
list [ 1 ] [ 2 ] = three
list [ 2 ] [ 0 ] = 1
list [ 2 ] [ 1 ] = 2
list [ 3 ] = 6
list [ 4 ] [ 0 ] = a
list [ 5 ] = {'set1', 'set2'}
list [ 6 ] = 5.4
list [ 7 ] [ 0 ] = None

I tried this piece of code:

def PrintListElements(list):
  for i in range(len(list)):
    try:
      for j in range(len(list[i])):
        print('list', '[', i, ']', '[', j, ']', '=', list[i][j])
    except TypeError:
        print('list', '[', i, ']', '=', list[i])
    else:
        print('list', '[', i, ']', '[', j, ']', '=', list[i][j])

PrintListElements(l)

However, the output is this:

list [ 0 ] = 7
list [ 1 ] [ 0 ] = one
list [ 1 ] [ 1 ] = two
list [ 1 ] [ 2 ] = three
list [ 1 ] [ 2 ] = three
list [ 2 ] [ 0 ] = 1
list [ 2 ] [ 1 ] = 2
list [ 2 ] [ 1 ] = 2
list [ 3 ] = 6
list [ 4 ] [ 0 ] = a
list [ 4 ] [ 0 ] = a
list [ 5 ] = {'set1', 'set2'}
list [ 6 ] = 5.4
list [ 7 ] [ 0 ] = None
list [ 7 ] [ 0 ] = None

I want to understand why the last element in each indexable type (i.e., list and tuple) are getting printed twice.

Also, any help regarding how I can get my desired output would be appreciated.

Thank you.

NOTE: I was getting the following errors:

TypeError: object of type 'int' has no len()
TypeError: 'set' object is not subscriptable

Hence, I added the exception-handling block.


Solution

  • This should work for any amount of nesting. This one uses recursion.

    l=[7, ['one', 'two', 'three'], (1, 2), 6, ('a',), {'set1', 'set2', (5,2)}, 5.4, [None]]
    FORMAT = " [ {} ]"
    
    def print_everything(l, indices=[]):
        for i,v in enumerate(l):
            if isinstance(v, list) or isinstance(v, tuple) or isinstance(v, set):
                new_index=[*indices]
                new_index.append(i)
                print_everything(v, new_index)
            else:
                print_string = 'list'
                for j in indices:
                    print_string += FORMAT.format(j)
                print_string += FORMAT.format(i)
                print_string += f' = {v}'
                print(print_string)
    
    print_everything(l)
    

    Output:

    list [ 0 ] = 7
    list [ 1 ] [ 0 ] = one
    list [ 1 ] [ 1 ] = two
    list [ 1 ] [ 2 ] = three
    list [ 2 ] [ 0 ] = 1
    list [ 2 ] [ 1 ] = 2
    list [ 3 ] = 6
    list [ 4 ] [ 0 ] = a
    list [ 5 ] [ 0 ] = set1
    list [ 5 ] [ 1 ] = set2
    list [ 5 ] [ 2 ] [ 0 ] = 5
    list [ 5 ] [ 2 ] [ 1 ] = 2
    list [ 6 ] = 5.4
    list [ 7 ] [ 0 ] = None
    

    If you input:

    l2 = [5, ['one', 'two', ['one2', 'two2', 'three3'], 'four'], (1,2,3,(4,5,6, (7,8))), 5.23, [None, 'something']]
    

    then you get:

    list [ 0 ] = 5
    list [ 1 ] [ 0 ] = one
    list [ 1 ] [ 1 ] = two
    list [ 1 ] [ 2 ] [ 0 ] = one2
    list [ 1 ] [ 2 ] [ 1 ] = two2
    list [ 1 ] [ 2 ] [ 2 ] = three3
    list [ 1 ] [ 3 ] = four
    list [ 2 ] [ 0 ] = 1
    list [ 2 ] [ 1 ] = 2
    list [ 2 ] [ 2 ] = 3
    list [ 2 ] [ 3 ] [ 0 ] = 4
    list [ 2 ] [ 3 ] [ 1 ] = 5
    list [ 2 ] [ 3 ] [ 2 ] = 6
    list [ 2 ] [ 3 ] [ 3 ] [ 0 ] = 7
    list [ 2 ] [ 3 ] [ 3 ] [ 1 ] = 8
    list [ 3 ] = 5.23
    list [ 4 ] [ 0 ] = None
    list [ 4 ] [ 1 ] = something
    

    EDIT: I didn't notice that you wanted to print the set as it is. For that you can remove the check isinstance(v, set) from my code.