numpy arrays
python programming
array manipulation
data processing
permutations

Insert element into numpy array and get all rolled permutations

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

When working with NumPy, "insert an element and get all rolled permutations" usually means two separate operations. First, generate every array formed by inserting one value at each possible position. Then, for each resulting array, compute its cyclic rotations with np.roll. Keeping those steps separate makes the code clearer and avoids confusion about what counts as a unique result.

Insert the Element at Every Position

If the source array has length n, there are n + 1 insertion positions. A small helper function makes that explicit:

python
1import numpy as np
2
3
4def insert_everywhere(arr, value):
5    arr = np.asarray(arr)
6    return [np.insert(arr, i, value) for i in range(arr.size + 1)]
7
8
9base = np.array([1, 2, 3])
10for candidate in insert_everywhere(base, 9):
11    print(candidate)

Output:

text
1[9 1 2 3]
2[1 9 2 3]
3[1 2 9 3]
4[1 2 3 9]

This gives you every insertion result, but not the rolled variants yet.

Generate All Cyclic Rolls

For one array, all cyclic rotations can be produced with np.roll:

python
1import numpy as np
2
3
4def all_rolls(arr):
5    arr = np.asarray(arr)
6    return [np.roll(arr, shift) for shift in range(arr.size)]
7
8
9example = np.array([1, 9, 2, 3])
10for rolled in all_rolls(example):
11    print(rolled)

Output:

text
1[1 9 2 3]
2[3 1 9 2]
3[2 3 1 9]
4[9 2 3 1]

That is a cyclic rotation set, not a full factorial permutation set. The distinction matters because the number of cyclic rolls is n, while the number of full permutations is n!.

Combine Insertion and Rolling

Once the two operations are defined, combining them is simple:

python
1import numpy as np
2
3
4def inserted_rolls(arr, value):
5    arr = np.asarray(arr)
6    results = []
7    for i in range(arr.size + 1):
8        inserted = np.insert(arr, i, value)
9        for shift in range(inserted.size):
10            results.append(np.roll(inserted, shift))
11    return results
12
13
14base = np.array([1, 2, 3])
15results = inserted_rolls(base, 9)
16
17for r in results:
18    print(r)

This returns every rolled version of every inserted variant. Depending on the data, some of those results may repeat.

Remove Duplicates When Values Repeat

If the source array already contains duplicate values, insertion plus rolling can generate identical arrays more than once. In that case, normalize arrays into tuples and use a set:

python
1import numpy as np
2
3
4def unique_inserted_rolls(arr, value):
5    unique = set()
6    for candidate in inserted_rolls(arr, value):
7        unique.add(tuple(candidate.tolist()))
8    return [np.array(item) for item in unique]
9
10
11base = np.array([1, 1, 2])
12unique_results = unique_inserted_rolls(base, 9)
13
14for r in unique_results:
15    print(r)

Using tuples for deduplication is usually the simplest approach because NumPy arrays themselves are not hashable.

Build a 2D Result Array When Shapes Match

If you want to keep the results in one NumPy structure, stack them into a 2D array:

python
1import numpy as np
2
3base = np.array([1, 2, 3])
4stacked = np.vstack(inserted_rolls(base, 9))
5
6print(stacked.shape)
7print(stacked)

This is handy for downstream vectorized processing, but it can consume a lot of memory if the input grows. Remember that the result count is (n + 1) * (n + 1) before deduplication.

Be Precise About the Goal

This topic often becomes messy because "rolled permutations" is ambiguous. You should decide which of these you actually need:

  • every insertion position only
  • every cyclic roll of one inserted array
  • every cyclic roll of every insertion result
  • all full permutations after insertion

Those are different problems with very different result sizes. If the requirement is truly "all full permutations," use itertools.permutations instead of np.roll.

Common Pitfalls

  • Mixing up cyclic rolls with full permutations and underestimating the difference in result count.
  • Calling np.insert once and expecting it to generate every insertion position automatically.
  • Ignoring duplicate results when the original array contains repeated values.
  • Forcing everything into one large stacked array before checking memory cost.
  • Writing the transformation as one dense expression instead of separating insertion and rolling into testable steps.

Summary

  • Treat insertion and cyclic rolling as two separate operations.
  • Use np.insert across every index from 0 to n.
  • Use np.roll to generate cyclic rotations for each inserted result.
  • Deduplicate with tuples when repeated values can create identical arrays.
  • Clarify whether you need rolls or full permutations before choosing the implementation.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

All Rights Reserved.