0

I need to read a file containing information on different lines - for example the file may contain

12345678910
abcdefghij
zyxwvutsrq

I will then need to read the code diagonally so my list would be:

(1bx)(2cw)(3dv)

I have tried using zip and just can't figure out a way to get it to work.

EDIT

Is there anyway to also make it take into account the diagonals before the top left corner for example:

(ay)(z) 

in the example file I used.

Edit 2: this is my almost complete code

with open(FileName) as diagonal :
    a = diagonal.read().splitlines()
    l = [a[i][i:] for i in range(len(a))]
    Diaglist = [''.join(i) for i in zip(*l)]

with open(FileName) as diagonal1 :
    b = diagonal1.read().splitlines()
    o = [b[i][:i] for i in range(len(b))]
    Diaglist1 = [''.join(i) for i in zip(*o)]

When I run the file I get the correct diagonals for the first with so from the top right to left but the second with so from the top right downwards I just get an empty list.

T.Lowe
  • 15
  • 4

2 Answers2

1

Do you mean:

>>> with open('file') as f:
...     l = f.read().splitlines()
>>> l
['12345678910', 'abcdefghij', 'zyxwvutsrq']

>>> l = [l[0]] + [l[1][1:]] + [l[2][2:]]  # remove 'a' from `l[1]` and `zy` from `l[2]`
>>> l
['12345678910', 'bcdefghij', 'xwvutsrq']

>>> list(zip(*l))  # zip them
[('1', 'b', 'x'), ('2', 'c', 'w'), ('3', 'd', 'v'), ('4', 'e', 'u'), ('5', 'f', 't'), ('6', 'g', 's'), ('7', 'h', 'r'), ('8', 'i', 'q')]

>>> [''.join(i) for i in list(zip(*l))]  # also join them
['1bx', '2cw', '3dv', '4eu', '5ft', '6gs', '7hr', '8iq']
>>> 

If you don't know how many lines in your file, we can use some code like [a[i][i:] for i in range(len(a))].

Try:

with open('file') as f:
    a = f.read().splitlines()

l = [a[i][i:] for i in range(len(a))]
final_list = [''.join(i) for i in zip(*l)]

print(final_list)

As your edit, you can change a[i][i:] to a[i][:i]. Very simple:

with open('file') as f:
    a = f.read().splitlines()

l = [a[i][:i] for i in range(len(a))]
final_list = [''.join(i) for i in zip(*l)][1:]  # since the first element in the list will be empty (`''`), remove it. 

print(final_list)
Remi Guan
  • 21,506
  • 17
  • 64
  • 87
  • The file can contain any number of rows/columns and can have any length. I tried to use the code you have typed with the actual file that I have and it didn't seem to work. – T.Lowe Dec 08 '15 at 00:04
  • That works amazingly man, thank you. Is here anyway to make it so it also checks the diagonals in the opposite way...I will edit my main post – T.Lowe Dec 08 '15 at 00:13
  • You're an absolute legend mate, thank you soo much. I've been stuck on this for hours now. – T.Lowe Dec 08 '15 at 00:28
  • @T.Lowe: No problem. Check [this question](http://stackoverflow.com/questions/509211/explain-pythons-slice-notation) to understand how did I do that. Also remember accept this answer if it's helpful :) – Remi Guan Dec 08 '15 at 00:42
  • Sorry to bother you anymore but can you please take a look at my last edit. – T.Lowe Dec 08 '15 at 00:55
  • @T.Lowe: Ah, I understand what's the problem now. Give me some time since I'm eating breakfast ;) – Remi Guan Dec 08 '15 at 01:06
  • @T.Lowe: Well, so now you're trying to zip `(ay)(z)`, what's the expect output? – Remi Guan Dec 08 '15 at 01:10
  • The expected output is one list that contains the diagonals for the entire file. – T.Lowe Dec 08 '15 at 01:19
  • Ah, I understand what the problem is. Because `zip()` only zip the list **5 times** if the smallest length element in that list is 5 like `'utsrq'` in the `['12345678910', 'bcdefghij', 'xwvutsrq', 'wvutsrq', 'vutsrq', 'utsrq']`. However in your example, maybe you just want to **reverse** the first list like `Diaglist[::-1]` gives you? – Remi Guan Dec 08 '15 at 01:34
0

The following will work for an arbitrary number of lines of the same length, and wraps the final diagonals. This may not be what you want.

def diagonals(lines):
    size = len(lines[0])
    positions = [[(i + x) % size for x in range(len(lines))] 
                 for i in range(size)]
    return ["".join([lines[i][p] for i, p in enumerate(posn)]) 
            for posn in positions]

>>> print(diagonals(['1234567891', 'abcdefghij', 'zyxwvutsrq']))
['1bx', '2cw', '3dv', '4eu', '5ft', '6gs', '7hr', '8iq', '9jz', '1ay']
donkopotamus
  • 22,114
  • 2
  • 48
  • 60