-1

I have a function insarrintomain which takes 2 arguments. The first one is main list, the second one is an insert list. I need to create a new list, where I will have all numbers from both arrays in increasing order. For example: main is [1, 2, 3, 4, 8, 9, 12], ins is [5, 6, 7, 10]. I should get [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12]

Here is my code:

def insarrintomain(main, ins):
    arr = []
    c = 0
    for i, el in enumerate(main):
        if c < len(ins):
            if el > ins[c]:
                for j, ins_el in enumerate(ins):
                    if ins_el < el:
                        c += 1
                        arr.append(ins_el)
                    else:
                        break
            else:
                arr.append(el)
        else:
            arr.append(el)
    return arr

What did I miss?

Michael S.
  • 3,050
  • 4
  • 19
  • 34
Timur
  • 11
  • 2
  • Nitpick: you're talking about _lists_ not arrays. – Chris Aug 31 '22 at 08:02
  • 1
    Welcome to Stack Overflow. "What do I miss?" Well, **what happens** when you try the code? **How is that different** from what is supposed to happen? – Karl Knechtel Aug 31 '22 at 08:02
  • Closed as a duplicate. Of the answers in the linked question, [this](https://stackoverflow.com/a/47255340/6890912) should answer your question. – blhsing Aug 31 '22 at 08:10

3 Answers3

3

Why not

new_array = main + insert
new_array.sort()
nikitira
  • 86
  • 7
2

The pyhonic way of solving this problem is something like this:

def insarrintomain(main, ins):
    new_list = main + ins
    new_list.sort()
    return new_list

In Python readability counts.
This code is pythonic because it’s easy to read: the function takes two lists, concatenates them into one new list, sorts the result and returns it.

Another reason why this code is pythonic is because it uses built-in functions. There is no need to reinvent the wheel: someone already needed to concatenate two lists, or to sort one. Built-in functions such as sort have been optimised for decades and are mostly written in C language. By no chance we can beat them using Python.


Let’s analyse the implementation from @RiccardoBucco.

That is perfect C code. You barely can understand what is happening without comments. The algorithm is the best possible for our case (it exploits the existing ordering of the lists) and if you can find in the standard libraries an implementation of that algorithm you should substitute sort with that.
But this is Python, not C. Solving your problem from scratch and not by using built-ins results in an uglier and slower solution.

You can have a proof of that by running the following script and watching how many time each implementation needs

import time
long_list = [x for x in range(100000)]

def insarrintomain(main, ins):
    # insert here the code you want to test
    return new_list

start = time.perf_counter()
_ = insarrintomain(long_list, long_list)
stop = time.perf_counter()

print(stop - start)

On my computer my implementation took nearly 0.003 seconds, while the C-style implementation from @RiccardoBucco needed 0.055 seconds.

chc
  • 498
  • 1
  • 4
  • 18
  • Of course I could use sort, but how do I do this algorithmically? – Timur Aug 31 '22 at 08:02
  • It depends on which algorithm you want to use. Here are some https://en.wikipedia.org/wiki/Sorting_algorithm. In any case it's always better to use built in functions over custom functions whenever they are available. They are usually faster and safer – chc Aug 31 '22 at 08:04
-1

A simple solution would be:

def insarrintomain(main, ins):
    return (main + ins).sorted()

But this solution is clearly not optimal (the complexity is high, as we are not using the fact that the input arrays are already sorted). Specifically, the complexity here is O(k * log(k)), where k is the sum of n and m (n is the length of main and m is the length of ins).

A better solution:

def insarrintomain(main, ins):
    i = j = 0
    arr = []
    while i < len(main) and j < len(ins):
        if main[i] < ins[j]:
            arr.append(main[i])
            i += 1
        else:
            arr.append(ins[j])
            j += 1
    while i < len(main):
        arr.append(main[i])
        i += 1
    while j < len(ins):
        arr.append(ins[j])
        j += 1
    return arr

Example:

>>> insarrintomain([1, 2, 3, 4, 8, 9, 12], [5, 6, 7, 10])
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12]

This solution is much faster for big arrays (O(k), where k is the sum of n and m, n is the length of main and m is the length of ins).

Riccardo Bucco
  • 13,980
  • 4
  • 22
  • 50