0

The concept is simple. I want to create a list of 26 by 26 and fill it with the alphabet. Except that each time, I have to shift one letter to the right.

Example:

  1. A, B, C, E, F, G...
  2. Z, A, B, C, E, F, G...
  3. Y, Z, A, B, C, E, F, G...

I made this code which works but it displayed the basic alphabet at the end. Looks like the array is resseted to the basic alphabet.

alphabet=["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"]
import numpy as np
Tableau=np.empty((26,26),dtype='<U1')

for k in range(len(alphabet)):
    for i in range(len(alphabet)):
        if i + k >= len(alphabet):
            i += k - len(alphabet)
        else:
            i += k

        Tableau[k][i] = alphabet[i]
        print(Tableau[k][i])
        print(alphabet[i], "\n")

I get ['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'] 26 times instead of getting the right result.

Bill Hileman
  • 2,798
  • 2
  • 17
  • 24
Dayrion
  • 23
  • 3

4 Answers4

1
`Matrix = [[chr(ord('A')+(x-y)%26) for x in range(26)] for y in range(26)]`

It uses a few tricks. First of all, list comprehension to make the 2D array. You don't need numpy. Second of all, it uses modulo arithmetic, chr() and ord().

`Matrix = [[x for x in range(26)] for y in range(26)]`

This will give you an array with each row:

`[0,1,2,...]`


`Matrix = [[(x-y) for x in range(26)] for y in range(26)]`

Does the shift for each row, but goes out of the 0-26 range

`[
[0,1,2,...]
[-1,0,1,2,...]
[-2,-1,0,1,2,...]
...
]`

`Matrix = [[((x-y)%26) for x in range(26)] for y in range(26)]`

Using mod 26, we put our numbers into the 0-25 range.

Now it's just a question of turning 0-25 into A-Z.

The built-ins chr() and ord() help you there.

Dean C Wills
  • 176
  • 6
1

You are over thinking it, there is no need to use numpy here. To shift a letter, just get the latest letter, remove it from the list and add it on the front, eg:

alphabet=["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"]
final_result = []
for i in range(len(alphabet)):
    el = alphabet[-1] # Get the first letter
    alphabet.pop() # Remove the latest letter
    alphabet = [el] + alphabet # Update the list, setting the first letter as the latest
    final_result.append(alphabet) # Append to the list containing the rotated alphabet

Note that: There are other ways to solve this issue, just demonstrated a way which is readable and easy to understand.

Adriano Martins
  • 1,788
  • 1
  • 19
  • 23
  • 1
    This prints the output similar to what the OP shows but the actual goal was, "create a list of 26 by 26 and fill it with the alphabet." This solution leaves behind no data structure of that description. – cdlane Apr 01 '18 at 05:12
0

The problem may be simpler than you're making it:

import numpy as np

ALPHABET = list("ABCDEFGHIJKLMNOPQRSTUVWXYZ")

LENGTH = len(ALPHABET)

tableau = np.empty((LENGTH, LENGTH), dtype='<U1')

for i in range(LENGTH):
    for j in range(LENGTH):
        k = (j - i) % LENGTH

        tableau[i][j] = ALPHABET[k]

print(tableau)
cdlane
  • 40,441
  • 5
  • 32
  • 81
0

A deque has a rotate method; turn your list into a deque; append the deque (as a list) to the final list; rotate; repeat 25 times.

import collections
alphabet=["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"]
alphabet = collections.deque(alphabet)
final = []
for _ in range(26):
    final.append(list(alphabet))
    alphabet.rotate()
wwii
  • 23,232
  • 7
  • 37
  • 77