0

I'm trying to write a file where you have 2 rows, with the first row being numbers and the 2nd row being letters. As an example, I was trying to do this with the alphabet.

list1=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
list2=list1+list1

abcList = [[],[]]

for i in range(len(list2)):
    i+=1
    if i % 5 == 0:
        if i>=10:
            abcList[0].append(str(i) + '     ')
        else:
            abcList[0].append(str(i) + ' ')
    elif i<=1:
        abcList[0].append(str(i) + ' ')
    else:
        abcList[0].append('  ')
for i,v in enumerate(list2):
    i+=1
    if i > 10:
        abcList[1].append(' '+v+' ')
    else:
        abcList[1].append(v+' ')

print(''.join(abcList[0]))
print(''.join(abcList[1]))

with open('file.txt','w') as file:
    file.write(''.join(abcList[0]))
    file.write('\n')
    file.write(''.join(abcList[1]))

The problem with the above setup is its very "hacky" (I don't know if its the right word). It "works", but its really just modifying 2 lists to make sure they stack on top of one another properly. The problem is if your list becomes too long, then the text wraps around, and stacks on itself instead of the numbers. I'm looking for something a bit less "hacky" that would work for any size list (trying to do this without external libraries, so I don't want to use pandas or numpy).

Edit: The output would be:

1       5         10
A B C D E F G H I J...etc.

Edit 2: Just thought I'd add, I've gotten this far with it so far, but I've only been able to make columns, not rows.

list1=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
list2=list1*2

abcList = [[],[]]

for i in range(len(list2)):
    i+=1
    if i % 5 == 0:
        if i>=5:
            abcList[0].append(str(i))
    elif i<=1:
        abcList[0].append(str(i))
    else:
        abcList[0].append('')
for i,letter in enumerate(list2):
    abcList[1].append(letter)

for number, letters in zip(*abcList):
    print(number.ljust(5), letters)

However, this no longer has the wrapping issues, and the numbers line up with the letters perfectly. The only thing now is to get them from columns to rows.

Output of above is:

1     A
      B
      C
      D
5     E
      F
      G
      H
      I
10    J
Red
  • 26,798
  • 7
  • 36
  • 58
samman
  • 559
  • 10
  • 29
  • Does this answer your question? https://stackoverflow.com/questions/39358742/converting-list-of-lists-into-a-table – Shivam Jha Jul 02 '20 at 20:47
  • Numpy arrays would do the trick... https://www.w3schools.com/python/numpy_intro.asp – theX Jul 02 '20 at 20:47
  • Could you show the expected output ? That would be easier – azro Jul 02 '20 at 20:48
  • I added the output, and as stated, I don't want to use numpy or pandas. – samman Jul 02 '20 at 20:55
  • @ShivamJha it sort of does. I've been able to use zip to aet the above output, but vertically since zip is an iteration and thus is displayed vertically instead of list in a list horizontally. – samman Jul 02 '20 at 21:12
  • @samman Does any of our answers satisfy you? If not, let me know how I can imrove it. – Red Jul 05 '20 at 22:23
  • @AnnZen Yes, I apologize I completely forgot about this question. I realized the issue I was having was my word processor was wrapping, thus preventing it from appearing aligned (despite being aligned like a table). Although, your answer specifically, none of the numbers are aligned with the proper alphabet (except for the when you do it in 6ths). – samman Jul 05 '20 at 22:51
  • @samman I know only one of them a the one you wanted, but I wasn't sure which, so I provided three options. – Red Jul 05 '20 at 22:52
  • @samman Is it on purpose that all the intervals are by 5 except the first one, which is by 4? – Red Jul 05 '20 at 22:56
  • @AnnZen yes. Although I realize I never specified the numbers should align with the letters, so I apologize for the unclear directions. All the below answer technically answer the original question, however none of them prevent wrapping issues once saved in a txt file. The only solution here is to create a break ( I found 50 to be a good number), that way you never reach the end of the word processor, and thus never wrap around ruining the alignment. – samman Jul 05 '20 at 23:02
  • @samman Well, the size of each character in txt files aren't equal, so I'm not too sure how to go about this, sorry. – Red Jul 05 '20 at 23:07
  • @AnnZen No problem, I ended up resolving it by doing the above but creating line breaks at every 50 values (thus eliminating the wrapping issue). Thank you for the answer and help though! – samman Jul 06 '20 at 00:20
  • @samman That's great! You can also post you solution as an answer to help other users :) – Red Jul 06 '20 at 00:22

3 Answers3

1

I mean, you could do something like this:

file_contents = """...""" # The file contents. I not the best at file manipulation


def parser(document):  # This function will return a nested list
    temp = str(document).split('\n')
    return [[line] for line in temp]  # List comprehension
parsed = parser(file_contents) 
# And then do what you want with that
theX
  • 1,008
  • 7
  • 22
1

Your expected output is a bit inconsistent, since in the first one, you have 1, 6, 11, 16... and in the second: 1, 5, 10, 15.... So I have a couple of possible solutions:


print(''.join(['  ' if n%5 else str(n+1).ljust(2) for n in range(len(list2))]))
print(''.join([c.ljust(2) for c in list2]))

Output:

1         6         11        16        21        26        31        36        41        46        51  
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

print(''.join(['  ' if n%5 else str(n).ljust(2) for n in range(len(list2))]))
print(''.join([c.ljust(2) for c in list2]))

Output:

0         5         10        15        20        25        30        35        40        45        50  
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 

print(''.join(['1 ']+['  ' if n%5 else str(n).ljust(2) for n in range(len(list2))][1:]))
print(''.join([c.ljust(2) for c in list2]))

Output:

1         5         10        15        20        25        30        35        40        45        50  
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

Red
  • 26,798
  • 7
  • 36
  • 58
1

If you are wanting to keep variable width strings aligned, you could use string formatting with a width equal to the maximum of the widths of the individual items in that position. (This example will work with more than any number of lists, by the way.)

list1 = ["", "5", "", "10", "", "4"]
list2 = ["A", "B", "C", "D", "EE", "F"]

lists = [list1, list2]

widths = [max(map(len, t)) for t in zip(*lists)]

for lst in lists:
    line = " ".join("{val:{width}s}".format(val=val, width=width)
                    for val, width in zip(lst, widths))
    print(line)

gives:

  5   10    4
A B C D  EE F
alani
  • 12,573
  • 2
  • 13
  • 23