You want to create a two-dimensional list of size 7x7 and display it on the screen. Then swap the main and secondary diagonals. After display the modified list on the screen. For this I use the following algorithm:

a=[] k=10 for r in range(7): a.append([]) for c in range(7): a[r].append(k) k+=1 print(a[0]);print(a[1]);print(a[2]);print(a[3]);print(a[4]);print(a[5]);print(a[6]) 

Python 3.5 is used.

  • What is the problem? - mkkik
  • can't swap diagonals - Cheepee
  • Show your code. - mkkik
  • And how can this be done at all if there are different number of elements? What is meant by "swap"? - andy.37
  • andy, not different, this is a 7x7 matrix - Cheepee

3 answers 3

 def swap1(a): n = len(a) for i in range(n): a[i][i], a[ni-1][i] = a[ni-1][i], a[i][i] def show(a): for r in a: print (', '.join(['{:2d}'.format(i) for i in r])) a = [[j + i*7 + 1 for j in range(7)] for i in range(7)] show(a) swap1(a) print() show(a) 

Result:

  1, 2, 3, 4, 5, 6, 7 8, 9, 10, 11, 12, 13, 14 15, 16, 17, 18, 19, 20, 21 22, 23, 24, 25, 26, 27, 28 29, 30, 31, 32, 33, 34, 35 36, 37, 38, 39, 40, 41, 42 43, 44, 45, 46, 47, 48, 49 43, 2, 3, 4, 5, 6, 49 8, 37, 10, 11, 12, 41, 14 15, 16, 31, 18, 33, 20, 21 22, 23, 24, 25, 26, 27, 28 29, 30, 17, 32, 19, 34, 35 36, 9, 38, 39, 40, 13, 42 1, 44, 45, 46, 47, 48, 7 
  • why do you have the values ​​of the side diagonal "up-legs" in the resulting matrix? those. [43, 37, 31, 25, 19, 13, 7] instead of [7, 13, 19, 25, 31, 37, 43] ? - MaxU
  • @MaxU: fxyz.ru from here: "The secondary diagonal of the matrix is ​​called the diagonal going from the lower left to the upper right corner." He himself first wrote the opposite. Well this is trivial to replace - andy.37
  • strange, they think differently here: Antidiagonal - (linear algebra) The diagonal of a matrix that leads from top-right towards bottom-left - MaxU

To swap the main (top-down left-right) and bottom-up left-right diagonals in the nxn matrix, there is an O(n) algorithm:

 >>> import numpy as np >>> a = np.arange(49).reshape(7, -1) >>> a array([[ 0, 1, 2, 3, 4, 5, 6], [ 7, 8, 9, 10, 11, 12, 13], [14, 15, 16, 17, 18, 19, 20], [21, 22, 23, 24, 25, 26, 27], [28, 29, 30, 31, 32, 33, 34], [35, 36, 37, 38, 39, 40, 41], [42, 43, 44, 45, 46, 47, 48]]) >>> old_main_diagonal = a.diagonal().copy() >>> np.fill_diagonal(a, np.flipud(a).diagonal()) >>> np.fill_diagonal(np.flipud(a), old_main_diagonal) >>> a array([[42, 1, 2, 3, 4, 5, 48], [ 7, 36, 9, 10, 11, 40, 13], [14, 15, 30, 17, 32, 19, 20], [21, 22, 23, 24, 25, 26, 27], [28, 29, 16, 31, 18, 33, 34], [35, 8, 37, 38, 39, 12, 41], [ 0, 43, 44, 45, 46, 47, 6]]) 

It is worth noting that np.flipud(a).diagonal() is O(1) (in numpy 1.9+), since no copy occurs.

numpy.flipud(a) returns the view of array a upside down. a.diagonal() returns a view to the main diagonal. numpy.fill_diagonal(a, value) replaces in place the main diagonal in a with value .

To swap the main and diagonal "top-down right-left":

 >>> a = np.arange(49).reshape(7, -1) >>> a array([[ 0, 1, 2, 3, 4, 5, 6], [ 7, 8, 9, 10, 11, 12, 13], [14, 15, 16, 17, 18, 19, 20], [21, 22, 23, 24, 25, 26, 27], [28, 29, 30, 31, 32, 33, 34], [35, 36, 37, 38, 39, 40, 41], [42, 43, 44, 45, 46, 47, 48]]) >>> old_main_diag_in_reverse = a.diagonal()[::-1].copy() >>> np.fill_diagonal(a, np.fliplr(a).diagonal()) >>> np.fill_diagonal(np.flipud(a), old_main_diag_in_reverse) >>> a array([[ 6, 1, 2, 3, 4, 5, 0], [ 7, 12, 9, 10, 11, 8, 13], [14, 15, 18, 17, 16, 19, 20], [21, 22, 23, 24, 25, 26, 27], [28, 29, 32, 31, 30, 33, 34], [35, 40, 37, 38, 39, 36, 41], [48, 43, 44, 45, 46, 47, 42]]) 
  • np.fill_diagonal() looks clearly better than my method and will most likely be faster - MaxU

Solution using NumPy (may be interesting for those who study NumPy):

 In [98]: import numpy as np In [99]: a = np.arange(1, 50).reshape(7, -1) In [100]: print(a) [[ 1 2 3 4 5 6 7] [ 8 9 10 11 12 13 14] [15 16 17 18 19 20 21] [22 23 24 25 26 27 28] [29 30 31 32 33 34 35] [36 37 38 39 40 41 42] [43 44 45 46 47 48 49]] In [101]: a[np.diag_indices_from(a)], a[:, ::-1][np.diag_indices_from(a)] = \ np.fliplr(a).diagonal().copy(), a.diagonal().copy() In [102]: print(a) [[ 7 2 3 4 5 6 1] [ 8 13 10 11 12 9 14] [15 16 19 18 17 20 21] [22 23 24 25 26 27 28] [29 30 33 32 31 34 35] [36 41 38 39 40 37 42] [49 44 45 46 47 48 43]] 
  • one
    From the gun on the sparrows)) + - andy.37
  • @ andy.37, I agree! but I myself was wondering how to do this in NumPy ... - MaxU