Search code examples
pythonpython-3.xformattingoutput

I don't understand the output of enumerate (0, 0), (1,[])


This is my output:

[['apples', 'oranges', 'cherries', 'banana'], ['Alice', 'Bob', 'Carol', 'David'], ['dogs', 'cats', 'moose', 'goose']]
(0, 0)
(1, ['apples', 'oranges', 'cherries', 'banana'])
(0, 1)
(1, ['Alice', 'Bob', 'Carol', 'David'])
(0, 2)
(1, ['dogs', 'cats', 'moose', 'goose'])

EXPLAIN THIS TO ME:

I do not understand what this output means(0,0),(1,[]),(0,1),...

When i added the enumeratate to the print_table(), that is when i got the output.

My data is a list of 3 lists so why do i get 5 lines of output?

EVERYTHING UNDER THIS IS JUST EXTRA INFORMATION

This is my code:

def calculate_widht(data):
    col_width = [0] * len(data)
    word_lenght = 0
    for i, words in enumerate(data):
        # print(i)
        # print(words)
        word_lenght = 0
        for word in words:
            if word_lenght < len(word):
                word_lenght = len(word)               
                col_width[i]= word_lenght
    return col_width


def print_table(width, data):
    print(data)
    for words in enumerate(data):
        for word in enumerate(words):
            print(word)
                
            


def main():
    data = [['apples', 'oranges', 'cherries', 'banana'],
            ['Alice', 'Bob', 'Carol', 'David'],
            ['dogs', 'cats', 'moose', 'goose']]
    start = calculate_widht(data)
    return print_table(start, data)


if __name__ == '__main__':
    main()

This is my exercises:

Write a function named printTable() that takes a list of lists of strings and displays it in a well-organized table with each column right-justified. Assume that all the inner lists will contain the same number of strings.

My output should look like this:

   apples Alice  dogs
  oranges   Bob  cats
 cherries Carol moose
   banana David goose

Solution

  • To understand the result you're getting you have to look in the docs, in particular here:

    enumerate(iterable, start=0)

    Return an enumerate object. iterable must be a sequence, an iterator, or some other object which supports iteration. The __next__() method of the iterator returned by enumerate() returns a tuple containing a count (from start which defaults to 0) and the values obtained from iterating over iterable.

    So, your outer for-loop

        for words in enumerate(data):
    

    produces tuples of the form (int, list) - your words. You can easily verify that by looking at a print of list(enumerate(data)). That means that in the next level of the looping

            for word in enumerate(words):
    

    you are looping over something like enumerate((int, list)), not over the enumeration of the inner lists, as you seem to expect. Therefore each first word has the form (0, int) and each second one has the form (1, list). This results in the following printing pattern:

    (0, 0)
    (1, <first list>)
    (0, 1)
    (1, <second list>)
    (0, 2
    (1, <third list>)
    ...
    

    Your use of enumerate doesn't make much sense, it's rather unclear what you want to achieve with it? Seems like you get the data in columns. So you could try something like the following instead:

    def print_table(data):
        widths = [max(map(len, column)) + 2 for column in data]
        table = "\n".join(
            "".join(item.rjust(width) for item, width in zip(row, widths))
            for row in zip(*data)
        )
        print(table)
    

    First determine the widths of the columns by taking the maximum length of the strings in them, + 2 for a buffer to make it look nicer. Then use zip to get the rows, right-justify the strings with the resp. width and "".join them, and then "\n".join the so built rows along line breaks.

    Result for

    data = [['apples', 'oranges', 'cherries', 'banana'],
            ['Alice', 'Bob', 'Carol', 'David'],
            ['dogs', 'cats', 'moose', 'goose']]
    

    is

        apples  Alice   dogs
       oranges    Bob   cats
      cherries  Carol  moose
        banana  David  goose