0

I have a list of lists and I want to print a row of items from each list.

I have this code:

tableData = [['apples', 'oranges', 'cherries', 'banana'],
             ['Alice', 'Bob', 'Carol', 'David'],
             ['dogs', 'cats', 'moose', 'goose']]
t = 0
for i in tableData:
    if t <= (len(i)): 
        print(tableData[0][t].rjust(8), tableData[1][t].rjust(5), tableData[2][t].rjust(5))
        t += 1

and this is the result I'm getting:

  banana David goose
  apples Alice  dogs
 oranges   Bob  cats

Why is the script not iterating for a fourth time? And what does it say about looping though list of lists in python?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Ali K.
  • 9
  • 2
  • 3
    `tableData` only has three rows. So `for i in tableData` will only iterate three times. – Mark Jun 08 '22 at 17:38
  • One option would be to loop using `for t in range(len(tableData[0])):` and put the `print` statement unconditionally in the loop. – alani Jun 08 '22 at 17:43
  • to pair ting together you can use the [zip](https://docs.python.org/3/library/functions.html#zip) function – Copperfield Jun 08 '22 at 17:53

3 Answers3

1

As the comments indicate the problem with your code was the outer for loop iterates over sublists, of which there are only 3.

Since your goal is to print columnwise, a simpler approach is to transpose the list of list (so columns become rows), then loop over the rows as follows.

Code

for column in zip(*tableData):
    print(column[0].rjust(8), column[1].rjust(5), column[2].rjust(5))

Generalization

To handle an arbitrary number of columns we can adapt solutions from Printing Lists as Tabular Data

column_format ="{:>8}" * len(tableData)     # right alignment of each field to width 8
for column in zip(*tableData):
    print(column_format.format(*column))

Output

  apples   Alice    dogs
 oranges     Bob    cats
cherries   Carol   moose
  banana   David   goose
DarrylG
  • 16,732
  • 2
  • 17
  • 23
0

Try this.

tableData = [['apples', 'oranges', 'cherries', 'banana'],
             ['Alice', 'Bob', 'Carol', 'David'],
             ['dogs', 'cats', 'moose', 'goose']]
t = 0
for a in range(len(tableData[0])):
    for i in tableData:
        print(i[t].rjust(8),end=' ')
    print()
    t += 1

Or Using zip function.

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

for a in zip(*tableData):
    for i in a:
        print(i.rjust(8),end=' ')
    print()

OUTPUT

  apples    Alice     dogs 
 oranges      Bob     cats 
cherries    Carol    moose 
  banana    David    goose
codester_09
  • 5,622
  • 2
  • 5
  • 27
0

this is the result I'm getting

I don't get this result with the code shown, although it would make sense if t were initially -1 rather than 0 (might make sense as something you were temporarily testing).

Why is the script not iterating for a fourth time?

Because the loop iterates for i in tableData, and there are only three lists in tableData.

The condition t <= (len(i)) does not make any sense. i is one of the lists, so len(i) is a bound on indexes into that list. But t does not function as an index into a sublist; it functions as an index into the list of lists - because it is incremented by a loop over the list of lists.

what does it say about looping though list of lists in python?

That it works exactly the same way as looping through a list of anything else in Python.

Each time through the list, i is one of the elements of tableData. In this case, those elements are lists.

You apparently want to combine elements from the separate lists, according to their position. In other words, you want to iterate over the lists in parallel, which is done with zip. I will close the question as a duplicate after providing the deeper explanation here, since that is the proper way to solve the problem.

But let's first debug the attempted approach.

We presume that each list in the list of lists has the same length. We want to iterate over one of those lists, in order to have the appropriate amount of iterations. Then we need an index each time through the loop, so that we can use it for each iteration. That's what t was doing in the original code. Here, we'll do it using enumerate, which is the normal tool (I'll show you another duplicate for that).

We will take away the useless and wrong if condition, and ignore the element that is returned from enumerate to use only the index. We will take away manual incrementing of the index, since enumerate is already taking care of it.

Finally, we can use modern string formatting to assemble the data.

That gives us:

for i, _ in enumerate(tableData[0]):
    print(f"{tableData[0][i]:>8} {tableData[1][i]:>5} {tableData[2][i]:>5}")

As an aside: please drop the habit of using i as a variable name for for loops. Remember that Python's for loop gives you an element of the original sequence, and not a numeric index. The name i wrongly suggests the latter.

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153