Copy an Array and delete doubles - python

I got this code
A = [1, 1, 1, 2, 2, 2, 3, 4, 5, 6, 6, 6, 7, 8, 8, 9]
B = [0 for b in range(16)]
skipped = 0
for i in range(16):
if A[i] == A[i-1]:
skipped += 1
else:
B[i-skipped] = A[i]
print(B)
The output:
[1, 2, 3, 4, 5, 2, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0]
it eliminates the doubles. But if i got an array where doubles are at more random index it fails, like:
The Array#2:
A = [1, 1, 1, 2, 2, 2, 3, 4, 5, 2, 2, 2, 7, 8, 8, 9]
The output#2
[1, 2, 3, 4, 5, 2, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0]
In the output#2 there is the value 2 at index 1 and index 5, but i just want to eliminate all the doubles.
Sum:
So basically my algorithm should copy the values from Array A to Array B and eliminate all doubles independent from their index.
EDIT: i have to put it in pseudocode so i cant use convert methods or functions like SET

You can use set to do it:
A = [1, 1, 1, 2, 2, 2, 3, 4, 5, 6, 6, 6, 7, 8, 8, 9]
B = set(A)
print(B)
This code returns a set. To convert set to list you can write some_list = list(B).
Another way to do what you need:
A = [1, 1, 1, 2, 2, 2, 3, 4, 5, 6, 6, 6, 7, 8, 8, 9]
B = []
for x in A:
if x not in B:
B.append(x)
print(B)

Related

sample n random permutations of a list in python [duplicate]

This question already has answers here:
python shuffling with a parameter to get the same result
(4 answers)
Closed 1 year ago.
I have a list of values such as:
lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
and I need to reproducibly return n random shuffles of this list.
Ideally, I need a function with seed such that f(lst, samples = 2, seed = 1234)
-> return two shuffles of the list lst such as:
[5, 7, 1, 6, 2, 8, 0, 4, 3, 9]
[8, 7, 3, 0, 1, 4, 5, 9, 6, 2]
Repeated execution of this function (with the same seed) would return the same two lists.
This works without numpy:
import sys
import random
some_seed = 123 # change this to get different shuffles
def n_shuffles(lst, n):
r = random.Random(some_seed)
for _ in range(n):
_l = lst[:]
r.shuffle(_l)
yield _l
l = list(range(10))
>>> [*n_shuffles(l, 3)]
[[8, 7, 5, 9, 2, 3, 6, 1, 4, 0], [7, 6, 3, 4, 1, 0, 2, 5, 9, 8], [1, 8, 5, 6, 4, 7, 9, 0, 2, 3]]
>>> [*n_shuffles(l, 3)]
[[8, 7, 5, 9, 2, 3, 6, 1, 4, 0], [7, 6, 3, 4, 1, 0, 2, 5, 9, 8], [1, 8, 5, 6, 4, 7, 9, 0, 2, 3]]
You can use np.copy
import numpy as np
lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
def shuffle_list(arr:list,samples:int,seed:int):
np.random.seed(seed)
res = []
for i in range(samples):
arr_copy=np.copy(arr)
np.random.shuffle(arr_copy)
res.append(arr_copy)
return res
#test
print(shuffle_list(lst,2,1234))
output:
[array([7, 2, 9, 1, 0, 8, 4, 5, 6, 3]), array([7, 3, 5, 1, 4, 8, 0, 2, 6, 9])]
Ok, it wasn't an exact duplicate, but the proposed topic has pretty much shown that re-setting the seed() is the key:
import random
def shuffles(l,n):
random.seed(4) # just the same one as in the referred topic
return [random.sample(l,k=len(l)) for i in range(n)]
print(shuffles([1,2,3,4],3))
print("again:")
print(shuffles([1,2,3,4],3))
will generate
[[2, 4, 1, 3], [4, 1, 3, 2], [1, 2, 3, 4]]
again:
[[2, 4, 1, 3], [4, 1, 3, 2], [1, 2, 3, 4]]

Array problems in for loop

I want to go from one array A of 10 elements to the array B of 100 elements.
Each element of B from 0 to 9 is equal to the element 0 of A
Each element of B from 10 to 19 is equal to the element 1 of A
....
Each element of B from 90 to 99 is equal to the element 9 of A
I did the following code but it does not work
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
A = np.asarray(a)
b = []
for i in range(len(A)*10):
b.append(0)
B = np.asarray(b)
for i in range(len(A)):
for j in range(9):
B[j]=A[i]
Expected result:
B [ 0,0,0,0,0,0,0,0,0,0,
1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2
...,
9,9,9,9,9,9,9,9,9,9 ]
You are saving values only in first 9 list elements. You have to 'scale' it by adding i*10 to index.
import numpy as np
a=[0, 1, 2, 3, 4, 5, 6, 7]
A = np.asarray(a)
b = []
for i in range(len(A)**2):
b.append(0)
B = np.asarray(b)
for i in range(len(A)):
for j in range(len(A)):
B[j + i*len(A)]=A[i]
print(B)
This works for me:
>>> a = [1,2,3]
>>> [ x for i in a for x in [i]*3]
[1, 1, 1, 2, 2, 2, 3, 3, 3]
>>>
You may replace 3 with 10 or whatever you like.
Answering the question from Jacob:
>>> [[a]*10 for a in A]
[[1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [2, 2, 2, 2, 2, 2, 2, 2, 2, 2], [3, 3, 3, 3, 3, 3, 3, 3, 3, 3]]
You should avoid loops with numpy whenever possible. It kind of defeats the point. Here you can just use repeat():
import numpy as np
a=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
A = np.asarray(a)
B = A.repeat(10)
B:
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9])
If want the a nested list, just reshape:
B = A.repeat(10).reshape(-1, 10)
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
[4, 4, 4, 4, 4, 4, 4, 4, 4, 4],
[5, 5, 5, 5, 5, 5, 5, 5, 5, 5],
[6, 6, 6, 6, 6, 6, 6, 6, 6, 6],
[7, 7, 7, 7, 7, 7, 7, 7, 7, 7],
[8, 8, 8, 8, 8, 8, 8, 8, 8, 8],
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]])
You can use numpy and specify how many iterations of each element you want:
import numpy as np
A = [1,2,3,4]
B = [np.full(10, a) for a in A]
print(B)
Or if you prefer to not use numpy, instead use:
A = [1,2,3,4]
B = [[a]*10 for a in A]
print(B)
Giving you the wanted list B
Try this:
a = [*range(10)]
b = []
for i in range(10):
b.extend([a[i]* 10])
B = np.asarray(b)
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b = []
for x in a:
b += [x] * 10
print b
This answer is better, idea from lenik
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b = [x for x in a for i in range(10)]
print b
Answer in a single line: print([item for sublist in [[i]*10 for i in range(1,10)] for item in sublist])
If a were a generic list and not an ordered sequence
In [20]: a = [1, 'a', 3.14159, False, {1:2, 3:4}]
you could do as follows
In [21]: [_ for _ in (zip(*(a for _ in a))) for _ in _]
Out[21]:
[1,
1,
1,
1,
1,
'a',
'a',
'a',
'a',
'a',
3.14159,
3.14159,
3.14159,
3.14159,
3.14159,
False,
False,
False,
False,
False,
{1: 2, 3: 4},
{1: 2, 3: 4},
{1: 2, 3: 4},
{1: 2, 3: 4},
{1: 2, 3: 4}]
list1=[]
list2=[]
for i in range (0,10,1):
list1.append(i)
print(list1)
for i in range (0,10,1):
for j in range (0,10,1):
j=i
list2.append(j)
print(list2)

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.

The Insertion Sort algorithm. What's happening step by step?

I'm a new data science student and I am trying to understand what exactly is happening inside the insertion sort algorithm.
Can anyone tell me what's happening step by step? It would be most appreciated.
Below is a code I wrote with some verbose so I could hopefully understand what was happening a little better but to no avail.
A = [4, 1, 7, 52, 10, 12]
B = [4, 1, 7, 52, 10, 12]
def InsertionSort(A):
for j in range(1, len(A)):
print("***************** LOOP", j, "*********************\n")
key = A[j]
i = j - 1
print("i:", i, " | A[i]:", A[i], " | key:", key, "\n")
print("IS i:", i, ">= 0 and", A[i], ">", key, "?", "\n")
while i >= 0 and A[i] > key:
print("TRUE:", i, ">= 0 and", A[i], ">", key, "\n")
A[i + 1] = A[i] # left cell switches places with right cell
i = i - 1
A[i + 1] = key
print("\n\n")
print("=================== END =====================")
InsertionSort(A)
print("A (not-sorted): ", B)
print("A (sorted): ", A)
I don't understand how it switches the numbers.
Insertion sort works by looking at each element in the array and moving it towards the beginning of the array until it's smaller than everything seen so far.
To do this, an outer loop considers each element in the array (skip element 0 because there's nothing to compare it with and you don't want to IndexError). The inner loop slides the element starting at the current i index leftward, comparing it against each previous element j-1 in the array until the section of the array seen so far is sorted.
Your debug output relies too heavily on text and numbers rather than a visual of the array, which is all that's needed to see the algorithm in action. I also recommend using a slightly larger array size.
As an aside, I recommend sticking to Python camel_case naming convention.
If you play with this code and walk through the output step by step and I think you'll see what's going on:
a = [7, 3, 6, 9, 4, 5, 8, 0, 1, 2]
def insertion_sort(a):
for i in range(1, len(a)):
j = i
print("moving %d:" % a[j])
while j > 0 and a[j-1] > a[j]:
a[j-1], a[j] = a[j], a[j-1]
j -= 1
print(a)
print(" " + " " * j + "^---")
print()
print("original: \n" + str(a) + "\n")
insertion_sort(a)
Output:
original:
[7, 3, 6, 9, 4, 5, 8, 0, 1, 2]
moving 3:
[3, 7, 6, 9, 4, 5, 8, 0, 1, 2]
^---
moving 6:
[3, 6, 7, 9, 4, 5, 8, 0, 1, 2]
^---
moving 9:
moving 4:
[3, 6, 7, 4, 9, 5, 8, 0, 1, 2]
^---
[3, 6, 4, 7, 9, 5, 8, 0, 1, 2]
^---
[3, 4, 6, 7, 9, 5, 8, 0, 1, 2]
^---
moving 5:
[3, 4, 6, 7, 5, 9, 8, 0, 1, 2]
^---
[3, 4, 6, 5, 7, 9, 8, 0, 1, 2]
^---
[3, 4, 5, 6, 7, 9, 8, 0, 1, 2]
^---
moving 8:
[3, 4, 5, 6, 7, 8, 9, 0, 1, 2]
^---
moving 0:
[3, 4, 5, 6, 7, 8, 0, 9, 1, 2]
^---
[3, 4, 5, 6, 7, 0, 8, 9, 1, 2]
^---
[3, 4, 5, 6, 0, 7, 8, 9, 1, 2]
^---
[3, 4, 5, 0, 6, 7, 8, 9, 1, 2]
^---
[3, 4, 0, 5, 6, 7, 8, 9, 1, 2]
^---
[3, 0, 4, 5, 6, 7, 8, 9, 1, 2]
^---
[0, 3, 4, 5, 6, 7, 8, 9, 1, 2]
^---
moving 1:
[0, 3, 4, 5, 6, 7, 8, 1, 9, 2]
^---
[0, 3, 4, 5, 6, 7, 1, 8, 9, 2]
^---
[0, 3, 4, 5, 6, 1, 7, 8, 9, 2]
^---
[0, 3, 4, 5, 1, 6, 7, 8, 9, 2]
^---
[0, 3, 4, 1, 5, 6, 7, 8, 9, 2]
^---
[0, 3, 1, 4, 5, 6, 7, 8, 9, 2]
^---
[0, 1, 3, 4, 5, 6, 7, 8, 9, 2]
^---
moving 2:
[0, 1, 3, 4, 5, 6, 7, 8, 2, 9]
^---
[0, 1, 3, 4, 5, 6, 7, 2, 8, 9]
^---
[0, 1, 3, 4, 5, 6, 2, 7, 8, 9]
^---
[0, 1, 3, 4, 5, 2, 6, 7, 8, 9]
^---
[0, 1, 3, 4, 2, 5, 6, 7, 8, 9]
^---
[0, 1, 3, 2, 4, 5, 6, 7, 8, 9]
^---
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
^---
Unlike bubble sort, Insertion sort does not merely swap numbers (conceptually).
First, it stores the value at current index j in a variable key.
Then it starts at just previous index i of current index (i = j - 1), and traverses backwards (i = i - 1) towards the beginning. For each index, it compares value with key (while i >= 0 and A[i] > key). If value at i is more than key, it shifts the value one index forward (A[i + 1] = A[i]), until it finds a value equal or lower than key. When such value is found, key should come just after that in sorted array, so it places key at next index i+1 (A[i + 1] = key). It repeats the same process for all elements and result is sorted array.
This will help more https://visualgo.net/bn/sorting?slide=8.
The function is ordering a given array. First it iterates over the elements of the array, starting from the second element:
for j in range(1, len(A)):
Then it compares element j (key) with element j-1 (A[i]):
while i >= 0 and A[i] > key:
In case element j-1 is bigger than element j it needs to swap them, so it does the swap:
A[i + 1] = A[i]
Now it needs to check if this is true also for element j-2, hence the while loop. Hope this helps a bit.

Python Array Index - Every X elements?

So I have a weird problem...
I'd like to process an array and take naturally rounded indices's out of it.
For example, if you have array...
pies = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
I'd like to take every 1.1st element out of it rounded naturally. So under this case:
pies[0::round(1.1x)]
Would output:
[0, 1, 2, 3, 4, 6, 7, 8, 9]
Because it would take out the following rounded positions:
pies[0]->pies[0]
pies[1.1]->pies[1]
pies[2.2]->pies[2]
pies[3.3]->pies[3]
pies[4.4]->pies[4]
pies[5.5]->pies[6]
pies[6.6]->pies[7]
pies[7.7]->pies[8]
pies[8.8]->pies[9]
Note we're not rounding the content - we're rounding the index.
As another example, consider:
pies = [0, 2, 5, 1, 3, 9, 2, 12, 33, 45]
pies[0::round(1.1x)]
Would output:
[0, 2, 5, 1, 3, 2, 12, 33, 45]
I'm wondering how you could do this in the most 'pythonic' way possible.
Thanks!
In [7]: pies = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [8]: stride=1.1
In [9]: [pies[x] for x in range(len(pies)) for x in [int(round(x*stride))] if x < len(pies)]
Out[9]: [0, 1, 2, 3, 4, 6, 7, 8, 9]
In the alternative, this seems like a good job for a generator function:
def rounding_iterator(seq, stride):
try:
i = 0
while True:
yield seq[int(round(i*stride))]
i += 1
except IndexError:
pass
pies = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print list(rounding_iterator(pies, 1))
print list(rounding_iterator(pies, 1.1))
print list(rounding_iterator(pies, .9))
Result:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9]
How about multiplying the value in the list by 1.1, rounding it, and converting it to an int to drop the decimal:
pies = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for pie in pies:
print int(round(pie * 1.1))
If it doesn't need to be one line...
def rounded_indices(ls):
result = []
original_index = 0
new_index = 0
while new_index < len(ls):
result.append(ls[new_index])
original_index += 1
new_index = int(round(1.1 * original_index))
return result
>>> pies = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> rounded_indices(pies)
[0, 1, 2, 3, 4, 6, 7, 8, 9]
I've edited this, so you need increment index with 1.1 and round it. Correct?
If so, it should be something like this:
>>> pies = [0, 1, 2, 3, 3, 2, 1, 77, 88, 99]
>>> print [ pies[int(round(x*0.1+x))] for x in xrange(len(pies)-1) ]
[0, 1, 2, 3, 3, 1, 77, 88, 99]
>>> pies = [0, 2, 5, 1, 3, 9, 2, 12, 33, 45]
>>> print [ pies[int(round(x*0.1+x))] for x in xrange(len(pies)-1) ]
[0, 2, 5, 1, 3, 2, 12, 33, 45]
>>>
Does this, what you want?
Same with numpy:
>>> import numpy as np
>>> pies = [0, 2, 5, 1, 3, 9, 2, 12, 33, 45]
>>> print [ pies[int(round(x))] for x in np.arange(0,len(pies)-1,1.1) ]
[0, 2, 5, 1, 3, 2, 12, 33, 45]
With numpy you can change multiplier:
>>> print [ pies[int(round(x))] for x in np.arange(0,len(pies)/1.1,1.1) ]
[0, 2, 5, 1, 3, 2, 12, 33, 45]
>>> print [ pies[int(round(x))] for x in np.arange(0,len(pies)/3.3,3.3) ]
[0]
>>> print [ pies[int(round(x))] for x in np.arange(0,len(pies)/2.2,2.2) ]
[0, 5, 3]
>>>

Categories

Resources