Efficiency between two sorting functions - python

I have created a two functions which sorts integers from lowest value to highest then back to low. Does this type of sort exist? Anyways, I have the following two sorting functions which I have created which produce the same output. I was wondering which is the most efficient of the two? Are there any improvements I can make to either?
sortMiddleMax1
Create a new reverse sorted list of original
Start from index 1 to length of list step by 2
sortMiddleMax2
Sorts the list in-place
Start from last index to 0 step by 2
I tried to make the second more efficient than the first. I did not create a new list in memory and I appended to the end instead of pushing the whole list right. Am I correct in this assumption?
Functions
def sortMiddleMax1(aList=None, verbose=False):
if aList == None or len(aList) < 2:
return aList
else:
sList = sorted(x, key=None, reverse=True)
if verbose: print sList
index = 1
while index < len(sList):
tmp = sList[index]
del sList[index]
sList.insert(0, tmp)
index+=2
if verbose: print sList
return sList
def sortMiddleMax2(aList=None, verbose=False):
if aList == None or len(aList) < 2:
return aList
else:
aList.sort()
if verbose: print aList
index = len(aList)-1
while index > 0:
tmp = aList[index]
del aList[index]
aList.append(tmp)
index-=2
if verbose: print aList
return aList
Main
x = [1,4,6,8,3,5,7,1,5,8,3,9,2,8]
print '############# sortMiddleMax1 #############'
x1 = sortMiddleMax1(x, True)
print '############# sortMiddleMax2 #############'
x2 = sortMiddleMax2(x, True)
Output
############# sortMiddleMax1 #############
[9, 8, 8, 8, 7, 6, 5, 5, 4, 3, 3, 2, 1, 1]
[8, 9, 8, 8, 7, 6, 5, 5, 4, 3, 3, 2, 1, 1]
[8, 8, 9, 8, 7, 6, 5, 5, 4, 3, 3, 2, 1, 1]
[6, 8, 8, 9, 8, 7, 5, 5, 4, 3, 3, 2, 1, 1]
[5, 6, 8, 8, 9, 8, 7, 5, 4, 3, 3, 2, 1, 1]
[3, 5, 6, 8, 8, 9, 8, 7, 5, 4, 3, 2, 1, 1]
[2, 3, 5, 6, 8, 8, 9, 8, 7, 5, 4, 3, 1, 1]
[1, 2, 3, 5, 6, 8, 8, 9, 8, 7, 5, 4, 3, 1]
############# sortMiddleMax2 #############
[1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 8, 8, 8, 9]
[1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 8, 8, 8, 9]
[1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 8, 8, 9, 8]
[1, 1, 2, 3, 3, 4, 5, 5, 6, 8, 8, 9, 8, 7]
[1, 1, 2, 3, 3, 4, 5, 6, 8, 8, 9, 8, 7, 5]
[1, 1, 2, 3, 3, 5, 6, 8, 8, 9, 8, 7, 5, 4]
[1, 1, 2, 3, 5, 6, 8, 8, 9, 8, 7, 5, 4, 3]
[1, 2, 3, 5, 6, 8, 8, 9, 8, 7, 5, 4, 3, 1]

You can use Python's extended slicing. [::2] means take every second element. [::-2] means take every second element from the end and work backwards. Here the first slice starts at 0 for even length list and 1 for odd length lists
>>> x = [1, 4, 6, 8, 3, 5, 7, 1, 5, 8, 3, 9, 2, 8]
>>> x = sorted(x)
>>> x[len(x)%2::2] + x[::-2]
[1, 2, 3, 5, 6, 8, 8, 9, 8, 7, 5, 4, 3, 1]

You can use list slice to get the result without for loop:
x = sorted([1,4,6,8,3,5,7,1,5,8,3,9,2,8])
x2 = x[::2] + x[1::2][::-1]

I suspect your two current versions perform exactly the same. However, they both can be improved by using slices to get at the values in the list, rather than by deleting and inserting values.
Each del and each insert is O(N) and you're doing N/2 of each, so the sort will be O(N^2). Slicing is O(N) as well, but only needs to be done twice. The time taken for the sort O(N log N) will dominate, asymptotically.
def sortMiddle3(aList):
s = sorted(aList) # sort the provided list
# now take the even indexed items, followed by the odd indexes in reverse
if len(s) % 2 == 0: # is the number of items even?
return s[::2] + s[-1::-2] # if so, the last item has an odd index
else:
return s[::2] + s[-2::-2]
Example output:
>>> x = [1,4,6,8,3,5,7,1,5,8,3,9,2,8]
>>> sortMiddle3(x)
[1, 2, 3, 5, 6, 8, 8, 9, 8, 7, 5, 4, 3, 1]

Related

How to expand a list to a certain size without repeating each individual list elements that n-times?

I'm looking to keep the individual elements of a list repeating for x number of times, but can only see how to repeat the full list x number of times.
For example, I want to repeat the list [3, 5, 1, 9, 8] such that if x=12, then I want to produce tthe following list (i.e the list continues to repeat in order until there are 12 individual elements in the list:
[3, 5, 1, 9, 8, 3, 5, 1, 9, 8, 3, 5]
I can do the below but this is obviously not what I want and I'm unsure how to proceed from here.
my_list = [3, 5, 1, 9, 8]
x = 12
print(my_list * 12)
[3, 5, 1, 9, 8, 3, 5, 1, 9, 8, 3, 5, 1, 9, 8, 3, 5, 1, 9, 8, 3, 5, 1, 9, 8, 3, 5, 1, 9, 8, 3, 5, 1, 9, 8, 3, 5, 1, 9, 8, 3, 5, 1, 9, 8, 3, 5, 1, 9, 8, 3, 5, 1, 9, 8, 3, 5, 1, 9, 8]
Your code repeats list 12 times. You need to repeat list until length is matched. This can achieved using Itertools - Functions creating iterators for efficient looping
from itertools import cycle, islice
lis = [3, 5, 1, 9, 8]
out = list(islice(cycle(lis), 12))
print(out)
Gives #
[3, 5, 1, 9, 8, 3, 5, 1, 9, 8, 3, 5]
More pythonic #
Use a for loop to access each element in list and iterate over 'length' times. Repeat Ith element you access through loop in same list until length matches.
lis = [3, 5, 1, 9, 8]
length = 12
out = [lis[i%len(lis)] for i in range(length)]
print(out)
Gives ##
[3, 5, 1, 9, 8, 3, 5, 1, 9, 8, 3, 5]
There are multiple ways to go about it. If x is the final length desired and lst is the list (please do not use list as a variable name because it overwrites the builtin list function), then you can do :
lst = (lst * (1 + x // len(lst)))[:x]
This multiplies the list by the smallest number needed to get at least N elements, and then it slice the list to keep only the first N. For your example :
>>> lst = [3, 5, 1, 9, 8]
>>> x = 12
>>> (lst * (1 + x // len(lst)))[:x]
[3, 5, 1, 9, 8, 3, 5, 1, 9, 8, 3, 5]
You could also use a loop, for example :
index = 0
while len(lst) < x:
lst.append(lst[index])
index += 1

Finding a next lowest number from a List in python

I have a list of arrays as follows:
Array =[3, 6, 5, 7, 2, 4, 3, 5, 4, 5, 4, 7, 6, 7, 1, 7, 4, 6, 3]
example:
Value = 3, 6, 5, 7, 2, 4, 3, 5, 4, 5, 4, 7, 6, 7, 1, 7, 4, 6, 3
valley/Peak = v, p, v, p, v, p, v, p, v, p, v, p, v, p, v, p, v, p,v
As Mark Ransom & SA.93 suggested, indexing in python starts from 0. Maybe you are more familiar with R... :) For your solution, try this;
def next_lowest_num(Array,num):
lst = []
for i in Array[Array.index(num):]:
if i >= num:
lst.append(i)
else:
lst.append(i)
break
return lst
print(next_lowest_num(Array=[3, 6, 5, 7, 2, 4, 3, 5, 4, 5, 4, 7, 6, 7, 1, 7, 4, 6, 3],num=3))
print(next_lowest_num(Array=[3, 6, 5, 7, 2, 4, 3, 5, 4, 5, 4, 7, 6, 7, 1, 7, 4, 6, 3],num=5))
# Output
[3, 6, 5, 7, 2]
[5, 7, 2]
Hope this Helps...
logic
assign the index to start from
assign the value of the starting index
make a loop starting from the starting index to the end of the loop
in the loop check if current number is smaller than the starting target
slice the list to create the result sublist
code
array = [3, 6, 5, 7, 2, 4, 3, 5, 4, 5, 4, 7, 6, 7, 1, 7, 4, 6, 3]
start_index = 0 # the index to start from
# start_index = int(input("Enter the index to start from: ")) # to take this a step further, you could ask the user for the index to start from
target = array[start_index] # the number in the starting index
for i in range(start_index, len(array)): # loop from the start index till the end
if array[i] < target: # if the current number is smaller than my traget
# split the list from the start index to the current index (+1 because the slice is not inclusive)
print(array[start_index:i+1])
break
if i == len(array)-1: # if we reached the end of the list
print('fail') # print the rest of the list
input
start_index = 0
array = [3, 6, 5, 7, 2, 4, 3, 5, 4, 5, 4, 7, 6, 7, 1, 7, 4, 6, 3]
output
[3, 6, 5, 7, 2]

Randomly generate a 9 × 9 list where the entries are integers between 1 and 9 with no repeat entries in any row or in any column

I wrote a code for :Randomly generate a 9 × 9 list where the entries are integers between 1 and 9 with no repeat entries in any row or in any column.
but my code does not solve the no repeat entry part.
matr=[ ]
#print(matr)
for i in range(9):
entry=[ ]
for j in range(9):
while len(entry)<9:
draw=randint(1,9)
while draw not in entry:
entry.append(draw )
matr.append(entry )
#print(matr )
#print(entry)
for i in matr:
print(i)
or this code:
print('--------list 1 to 9--------------------------------------')
list=[ i for i in range(1,10) ]
print(list)
print('---------shuffle list-------------------------------------')
matr=[ ]
entry=list
for i in range(9):
entry=entry.copy()
shuffle(entry )
print(entry )
matr.append(entry)
print(matr)
You're looking to produce a random (valid) sudoku board. This is not trivial and a trial/error approach with random numbers will take forever to produce a valid result. Here's a sudoku generator that will do it using dynamic programming:
import random
groups = [ p//27*3+p%9//3 for p in range(81) ]
colNums = [ set(range(1,10)) for _ in range(9) ]
rowNums = [ set(range(1,10)) for _ in range(9) ]
grpNums = [ set(range(1,10)) for _ in range(9) ]
sudoku = [ [0]*9 for _ in range(9) ]
pos = 0
tried = [ set() for _ in range(81)]
while pos < 81:
row,col,group = pos//9,pos%9,groups[pos]
previousNumber = sudoku[row][col]
if previousNumber != 0: # make backtracked number available again
sudoku[row][col] = 0
colNums[col].add(previousNumber)
rowNums[row].add(previousNumber)
grpNums[group].add(previousNumber)
available = colNums[col] & rowNums[row] & grpNums[group]
available -= tried[pos]
if available: # select an available number at random
number = random.choice(list(available))
sudoku[row][col] = number
colNums[col].discard(number)
rowNums[row].discard(number)
grpNums[group].discard(number)
tried[pos].add(number)
pos += 1
else:
tried[pos] = set() # no available number, backtrack to previous position
pos -= 1
for line in sudoku:
print(line)
The algorithm attempts to place a number at each of the 81 positions sequentially. If there is a conflict it will try the next available number for that position. If there are no numbers that will fit at that position, then it backtracks to the previous position and tries the next available number there. It will move back and forth through the 81 positions until it manages to place a valid number at the last position.
In order to quickly check if a number is valid at a given position, the algorithm maintains 3 lists of sets. One for the rows, one for the columns and one for the nine 3x3 blocks. These sets contain the unused numbers for a given row, column or block. Each time a number is placed on the board, it is removed from the corresponding row/column/block sets. This makes it unavailable for all subsequent positions that are on the same row, column or block.
When the algorithm needs to backtrack, it returns the number at the previous position to its 3 availability sets. The position to which the algorithm is backtracking will move on to another number so the previously attempted number must become available for subsequent positions.
The positions are numbered from 0 to 80 to facilitate tracking and comparisons in sets. These position numbers can easily be converted to row and column using simple division and modulo operators. The conversion to group numbers is a little bit more complicates but it is also just a matter of division and modulo.
Variables used:
groups: conversion from a position number to a group number
colNums: sets of available positions for the 9 columns
rowNums: sets of available positions for the 9 rows
grpNums: sets of available positions for the 9 groups (3x3 blocks)
sudoku: the final board (9 rows of 9 numbers)
pos: current position where an attempt to place a number is being made
tried: set of numbers that have already been tried at each position so far. When backtracking the current set is cleared because the availability of positions will be different once the previous position is changed.
row,col,group are indexes corresponding to the current position (pos)
If you don't want the 3x3 blocks restriction, you can easily remove it by deleting the parts of the code that use/assign the group, groups and grpNums variables.
In that case, there is a much simpler (and faster) technique to produce a random matrix that meets the row/column unicity constraint:
import random
numbers = random.sample(range(1,10),9)
cols = random.sample(range(9),9)
rows = random.sample(range(9),9)
square = [[numbers[(r+c)%9] for c in cols] for r in rows]
for line in square: print(line)
[8, 9, 1, 7, 6, 4, 5, 3, 2]
[5, 2, 9, 6, 4, 3, 1, 8, 7]
[2, 4, 6, 8, 5, 1, 7, 9, 3]
[1, 7, 2, 4, 3, 8, 9, 5, 6]
[7, 3, 4, 5, 1, 9, 6, 2, 8]
[3, 1, 5, 2, 7, 6, 8, 4, 9]
[4, 5, 8, 9, 2, 7, 3, 6, 1]
[9, 6, 7, 3, 8, 5, 2, 1, 4]
[6, 8, 3, 1, 9, 2, 4, 7, 5]
Note that this may not produces all of the valid random matrices
To explain this one, it is best to start with a simple matrix of sequential indexes where each row is offset by one more than the preceding row:
matrix = [ [(r+c)%9 for c in range(9)] for r in range(9) ]
[0, 1, 2, 3, 4, 5, 6, 7, 8]
[1, 2, 3, 4, 5, 6, 7, 8, 0]
[2, 3, 4, 5, 6, 7, 8, 0, 1]
[3, 4, 5, 6, 7, 8, 0, 1, 2]
[4, 5, 6, 7, 8, 0, 1, 2, 3]
[5, 6, 7, 8, 0, 1, 2, 3, 4]
[6, 7, 8, 0, 1, 2, 3, 4, 5]
[7, 8, 0, 1, 2, 3, 4, 5, 6]
[8, 0, 1, 2, 3, 4, 5, 6, 7]
As you can see each row has indexes 0 to 8 (so no repetitions) and each column also has indexes 0 to 8 with no repetition because of offsetting.
Now if we create a list of numbers from 1 to 9 and shuffle it, we can replace the indexes in the matrix by the corresponding number in the shuffled list. Since each index maps to a different number, the resulting matrix will not have any repetitions on lines or columns.
numbers = random.sample(range(1,10),9) # [1, 5, 9, 8, 3, 7, 6, 2, 4]
matrix = [ [numbers[i] for i in row] for row in matrix ]
[1, 5, 9, 8, 3, 7, 6, 2, 4]
[5, 9, 8, 3, 7, 6, 2, 4, 1]
[9, 8, 3, 7, 6, 2, 4, 1, 5]
[8, 3, 7, 6, 2, 4, 1, 5, 9]
[3, 7, 6, 2, 4, 1, 5, 9, 8]
[7, 6, 2, 4, 1, 5, 9, 8, 3]
[6, 2, 4, 1, 5, 9, 8, 3, 7]
[2, 4, 1, 5, 9, 8, 3, 7, 6]
[4, 1, 5, 9, 8, 3, 7, 6, 2]
Finally we can shuffle the rows to get a more random organization of the matrix
random.shuffle(matrix)
[5, 9, 8, 3, 7, 6, 2, 4, 1]
[9, 8, 3, 7, 6, 2, 4, 1, 5]
[1, 5, 9, 8, 3, 7, 6, 2, 4]
[7, 6, 2, 4, 1, 5, 9, 8, 3]
[2, 4, 1, 5, 9, 8, 3, 7, 6]
[6, 2, 4, 1, 5, 9, 8, 3, 7]
[4, 1, 5, 9, 8, 3, 7, 6, 2]
[8, 3, 7, 6, 2, 4, 1, 5, 9]
[3, 7, 6, 2, 4, 1, 5, 9, 8]
and columns:
cols = random.sample(range(9),9) # [7, 4, 3, 0, 8, 1, 2, 5, 6]
matrix = [[matrix[r][c] for c in cols] for r in range(9)]
[4, 7, 3, 5, 1, 9, 8, 6, 2]
[1, 6, 7, 9, 5, 8, 3, 2, 4]
[2, 3, 8, 1, 4, 5, 9, 7, 6]
[8, 1, 4, 7, 3, 6, 2, 5, 9]
[7, 9, 5, 2, 6, 4, 1, 8, 3]
[3, 5, 1, 6, 7, 2, 4, 9, 8]
[6, 8, 9, 4, 2, 1, 5, 3, 7]
[5, 2, 6, 8, 9, 3, 7, 4, 1]
[9, 4, 2, 3, 8, 7, 6, 1, 5]
The solution (above) combines these steps into a single list comprehension but uses exactly the same approach.
Using the same approach, it is also possible to produce a random sudoku board (with the 3x3 block constraint). The formula for the offsets is a bit more complex and the shuffling of rows and columns can only be done within and between block groups.
from random import sample
base = 3 # Will generate any size of random sudoku board instantly
side = base*base
nums = sample(range(1,side+1),side) # random numbers
board = [[nums[(base*(r%base)+r//base+c)%side] for c in range(side) ] for r in range(side)]
rowGr = sample(range(base),base) # random rows/horizontal blocks
rows = [ r for g in rowGr for r in sample(range(g*base,(g+1)*base),base) ]
colGr = sample(range(base),base) # random column/vertical blocks
cols = [ c for g in colGr for c in sample(range(g*base,(g+1)*base),base) ]
board = [[board[r][c] for c in cols] for r in rows]
for line in board:print(line)
[7, 5, 3, 6, 9, 4, 1, 2, 8]
[6, 9, 4, 1, 2, 8, 7, 5, 3]
[1, 2, 8, 7, 5, 3, 6, 9, 4]
[2, 8, 7, 5, 3, 6, 9, 4, 1]
[5, 3, 6, 9, 4, 1, 2, 8, 7]
[9, 4, 1, 2, 8, 7, 5, 3, 6]
[8, 7, 5, 3, 6, 9, 4, 1, 2]
[3, 6, 9, 4, 1, 2, 8, 7, 5]
[4, 1, 2, 8, 7, 5, 3, 6, 9]
Steps
Generate a shuffled list
Left rotated by 1 to generate the matrix
Shuffle rows in matrix
Shuffle cols in matrix (optional)
from random import shuffle
a = list(range(10))
shuffle(a)
# Use slicing to left rotate
m = [a[i:] + a[:i] for i in range(10)]
# Shuffle rows in matrix
shuffle(m)
# Shuffle cols in matrix (optional)
m = list(map(list, zip(*m))) # Transpose the matrix
shuffle(m)
print('\n'.join(map(str, m)))
If you just need 1 matrix and no variation is expected, then you can keep shifting array to either right or left. Here is an example:
def cyclic_rotate(input):
return [input[-1]] + input[0:-1]
if __name__ == "__main__":
result = []
input = [i for i in range(9)]
prev = input
for i in range(9):
shifted_arr = cyclic_rotate(prev)
result.append(shifted_arr)
prev = shifted_arr
# Does only pretty print of 2-D matrix
print('\n'.join(['\t'.join([str(cell) for cell in row]) for row in result]))
Try this and you will get what you want:
>>> matrix = []
>>> for i in range(1,10):
... temp = []
... for j in range(i,i+9):
... if j >= 10:
... temp.append(int(j%10)+1)
... else:
... temp.append(j)
... matrix.append(temp)
...
>>> matrix
[[1, 2, 3, 4, 5, 6, 7, 8, 9], [2, 3, 4, 5, 6, 7, 8, 9, 1], [3, 4, 5, 6, 7, 8, 9, 1, 2], [4, 5, 6, 7, 8, 9, 1, 2, 3], [5, 6, 7, 8, 9, 1, 2, 3, 4], [6, 7, 8, 9, 1, 2, 3, 4, 5], [7, 8, 9, 1, 2, 3, 4, 5, 6], [8, 9, 1, 2, 3, 4, 5, 6, 7], [9, 1, 2, 3, 4, 5, 6, 7, 8]]
Hope this helps you.

Edit the value of every Nth item in a list

What's the most pythonic way of performing an arithmetic operation on every nth value in a list? For example, if I start with list1:
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
I would like to add 1 to every second item, which would give:
list2 = [1, 3, 3, 5, 5, 7, 7, 9, 9, 11]
I've tried:
list1[::2]+1
and also:
for x in list1:
x=2
list2 = list1[::x] + 1
You could use slicing with a list comprehension as follows:
In [26]: list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
In [27]: list1[1::2] = [x+1 for x in list1[1::2]]
In [28]: list1
Out[28]: [1, 3, 3, 5, 5, 7, 7, 9, 9, 11]
numpy allows you to use += operation with slices too:
In [15]: import numpy as np
In [16]: l = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
In [17]: l[1::2] += 1
In [18]: l
Out[18]: array([ 1, 3, 3, 5, 5, 7, 7, 9, 9, 11])
Use enumerate and a list comprehension
>>> list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> [v+1 if i%2!=0 else v for i,v in enumerate(list1)]
[1, 3, 3, 5, 5, 7, 7, 9, 9, 11]
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for i in range(1, len(list1), 2):
list1[i] +=1
print(list1)
using i%2 seems not very efficient
Try this:
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for i in range(1,len(list1),2):
list1[i] += 1
You can create an iterator representing the delta (itertools.cycle([0, 1]) and then add its elements to your existing list.
>>> list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> [a + b for a,b in zip(list1, itertools.cycle([0,1]))]
[1, 3, 3, 5, 5, 7, 7, 9, 9, 11]
>>>
a = [i for i in range(1,11)]
#a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
b = [a[i]+1 if i%2==1 else a[i] for i in range(len(a))]
#b = [1, 3, 3, 5, 5, 7, 7, 9, 9, 11]

Made typo, Python function still works. Why?

I've been learning programming and Python for about a month now using Udacity. For one of the questions we are supposed to write a function that checks if a sudoku list passed in is valid.
In the for loop below, I wanted to iterate through row and col at the same time with both the original and transposed list using zip() but mistakenly left in row in the second half of my or statement. I ran it and to my surprise, it still continued to return a correct answer.
def check_sudoku(array):
is_sudoku = True
reference = range(1, len(array) + 1)
transposed = zip(array)
for row, col in zip(array, transposed):
if sorted(row) != reference or sorted(row) != reference:
is_sudoku = False
break
return is_sudoku
My guess is it's because I defined is_sudoku = True by default, and I'm comparing rows with a reference list so it catches invalid values even if my transpose didn't work. When I replaced the second row with col though, it broke.
My question is, is my guess right? If not, why does this code work and how could I better write this?
Thanks! (Pasted on codepad as well if you want to see what lists I passed in - http://codepad.org/IXDlZuUu)
If the correct value was False, then your function works because at some point sorted(row) != reference. As for rewriting it, I'd think something like this would be more clear:
def check_sudoku(array):
reference = range(1, len(array) + 1)
transposed = zip(array)
for row, col in zip(array, transposed):
if sorted(row) != reference or sorted(row) != reference:
return False
return True
Additionally, it's pretty hard for me to see why you do transposed = zip(array) and then zip(array, transposed). As far as I can tell that just takes a list like [1, 2, 3] and turns it into [(1, (1,)), (2, (2,)), (3, (3,))].
If you are looking to iterate through the rows and columns, here's one method that works.
>>> rows = incorrect
>>> cols = [[row[i] for i in range(len(rows[0]))] for row in rows]
>>> cols = [[row[i] for row in rows] for i in range(len(row))]
>>> cols
[[4, 6, 3, 9, 7, 8, 1, 5, 2], [1, 5, 9, 6, 3, 2, 4, 8, 7], [2, 8, 7, 4, 5, 1, 9, 3, 6], [3, 9, 5, 2, 1, 7, 6, 4, 8], [6, 4, 2, 3, 8, 9, 5, 7, 1], [7, 1, 8, 5, 4, 6, 3, 2, 9], [8, 3,
1, 7, 6, 4, 2, 9, 5], [5, 2, 6, 8, 9, 3, 7, 1, 4], [1, 7, 4, 1, 2, 5, 8, 6, 3]]
>>> rows
[[4, 1, 2, 3, 6, 7, 8, 5, 1], [6, 5, 8, 9, 4, 1, 3, 2, 7], [3, 9, 7, 5, 2, 8, 1, 6, 4], [9, 6, 4, 2, 3, 5, 7, 8, 1], [7, 3, 5, 1, 8, 4, 6, 9, 2], [8, 2, 1, 7, 9, 6, 4, 3, 5], [1, 4,
9, 6, 5, 3, 2, 7, 8], [5, 8, 3, 4, 7, 2, 9, 1, 6], [2, 7, 6, 8, 1, 9, 5, 4, 3]]

Categories

Resources