(Python) Insert multiple elements into a list at different positions

Question:

I’m a student, I am working on a personal project which deals with images.
basically, I’m trying to make my own image scrambler, first I convert an image into 1D array of rgb values of image.

then I send this list into this function which basically scrambles the values of list (recursively), and is also reversible:

def split_and_flip(array:list) -> list:
    """
    divides the list into 2 halves and flips each half, joins the flipped halves and returns single list
    does the same thing with each half recursively if the list contains even number of items, 
    because array with odd number items cannot be split and obtained back in original form.
    where as arary with even number items can be split recursively and can be obtained back
    as original form of array.

    :param array: list
    :return: list - modified
    """
    size = len(array)
    halfsize_int = size // 2
    h1 = array[:halfsize_int]
    h2 = array[halfsize_int:]
    s1 = halfsize_int
    s2 = size - halfsize_int
    # first half
    if s1%2==0:
        h1 = split_and_flip(h1)
    # second half
    if s2%2==0:
        h2 = split_and_flip(h2)
    return h1[::-1] + h2[::-1]

but, as you can see, if the list is having odd numbers of values, the scrambling and unscrambling won’t be possible. or atleast, scrambling won’t be as good.
to solve this problem, I came up with this idea:

To Scramble the image:

  1. Add dummy values into the list until the size of the list becomes 2^n
  2. use split_and_flip(array) on this array.
  3. remove all the dummy values from the scrambled array.
  4. convert the scrambled array back to image.

To Unscrambling the image :

  1. make a new_array and do the steps 1 and 2 from above on the new array.
  2. now know all the locations where dummy values end up, store the indices of dummy values in a list indices
  3. insert the dummy values in the array at indices, call it array. (I am doing this step in order to obtain back the original unscrambled array of image)
  4. now use split_and_flip(array)
  5. remove all the dummy values.
  6. convert this array to image.

We now have successfully unscrambled the image.
but while doing this, I came across this problem:

the problem I’m getting is in step 3 of unscrambling the image.
I have a list array, and another list indices which consists of integers. and some value val .
I want to insert the val in arr at different indices, and these indices are stored in indices.

is there a function which can do this job quickly?

I tried this code:

def insert_values(array,indices,val):
    for index in indices:
        array.insert(index,value)
    return array

This code works, but I’m working with large arrays and there can be way too many insertions to be done depending on size of the image,
so.. my method is taking a LOT of time.

I came up with this idea of scrambling myself (idk if this is already done by someone else or not). that’s why I am committed to making this work.

is there any faster way of doing this? perhaps using some library like numpy or pandas?
(I googled, but I didn’t find the solution for this specific problem)
or is there any other approach for scrambling that I can take? (I really wanna do my idea though)

Asked By: UraniumX92

||

Answers:

A simpler option would be to use random.shuffle with a known seed, and then ‘unshuffle’ the list later using the same seed.

The following program should do what you want:

import random

def shuffle(data, seed):
    # Take a copy of data
    shuffled = data[:]
    # Set the new random seed
    random.seed(seed)
    # shuffle the data
    random.shuffle(shuffled)
    # reset the seed (to avoid problems using random elsewhere)
    random.seed()
    return shuffled

def unshuffle(shuffled, seed):
    # Make a list of numbers the same length as the shuffled data
    index = list(range(len(shuffled)))
    # Shuffle this list using the same seed
    index_shuffled = shuffle(index, seed)
    # Zip the shuffled data and index together
    unshuffled = list(zip(shuffled, index_shuffled))
    # Sort the pairs to unshuffle them, and return a list of just the data values
    return [x for x, y in sorted(unshuffled, key=lambda x: x[1])]

if __name__ == "__main__":
    seed = 123
    data = ['a', 'b', 'c', 'd', 'e']

    print(data)
    shuf = shuffle(data, seed)
    print(shuf)
    unshuf = unshuffle(shuf, seed)
    print(unshuf)
Answered By: match