Avión
Avión

Reputation: 8396

Filling an array with missing contigous numbers and getting the index

Having the list (no repeated values):

[67000, 67002, 67003, 67004, 67005, 67006, 67009]

I want to fill the list with the contigous numbers that are missing on it, so my desired output would be:

[67000, 67001, 67002, 67003, 67004, 67005, 67006, 67007, 67008, 67009]

And also get the index of the items that have been added to the list:

indx_list = [1,7,8]

This is my try:

lista_num = [67000, 67002, 67003, 67004, 67005, 67006, 67009]
for i in xrange(len(lista_num)-1):
    if lista_num[i] != lista_num[i+1]-1:
        print lista_num[i]
        lista_n = lista_num[i]
        lista_nu = lista_num[i+1]

        while lista_n < lista_nu-1:
            lista_n = lista_n + 1
            lista_num.insert(i+1, lista_n)
    else:
        print "ok"

But I'm getting the following output, which is not the desired output. I think I'm messing with the indexes.

[67000, 67001, 67002, 67003, 67004, 67005, 67006, 67009]

I haven't tried the part of getting the index of the items as this first step of getting the contigous number list is not even working.

How can I fix my code and archieve my goal? Thanks in advance.

Upvotes: 2

Views: 85

Answers (3)

Martin Evans
Martin Evans

Reputation: 46779

Your list appears to be sorted, so by definition the first entry is the smallest, and the last the greatest avoiding the need to find them. If this is always the case, simply create a new list as follows:

lista_num = [67000, 67002, 67003, 67004, 67005, 67006, 67009]
listb_num = range(lista_num[0], lista_num[-1]+1)

To determine which items were added you could do the following:

missing_items_set = set(listb_num).difference(set(lista_num))
print missing_items_set

set([67008, 67001, 67007])

This could be converted to a list and sorted:

missing_items_list = list(missing_items_set)
missing_items_list.sort()
print missing_items_list

[67001, 67007, 67008]

If lista_num[0] was subtracted from each, that would give you indexes.

Upvotes: 0

Kasravnd
Kasravnd

Reputation: 107337

You have 2 problem in your code,first is the range if your main for loop, you need to loop on len(lista_num) and you dont need -1, second is that you need to increase i within while loop :

lista_num = [67000, 67002, 67003, 67004, 67005, 67006, 67009]
for i in xrange(len(lista_num)):
    if lista_num[i] != lista_num[i+1]-1:
        lista_n = lista_num[i]
        lista_nu = lista_num[i+1]

        while lista_n < lista_nu-1:
            lista_n = lista_n + 1
            lista_num.insert(i+1, lista_n)
            i=i+1

print lista_num 

result :

[67000, 67001, 67002, 67003, 67004, 67005, 67006, 67007, 67008, 67009]

But as a more pythonic way you can use itertools module :

from itertools import izip,chain
lista_num = [67000, 67002, 67003, 67004, 67005, 67006, 67009]
lista_num.append(lista_num[-1]+1)
print list(chain.from_iterable(xrange(i,j) for i,j in izip(lista_num,lista_num[1:])))
[67000, 67001, 67002, 67003, 67004, 67005, 67006, 67007, 67008, 67009]

Upvotes: 1

Ami Tavory
Ami Tavory

Reputation: 76336

Suppose your original list is

a = [67000, 67002, 67003, 67004, 67005, 67006, 67009]

So your required target list can be found with

out = range(min(a), max(a) + 1)

and the added indices can be found with

[i for (i, v) in enumerate(out) if v not in a]

(The complexity of the last line is quadratic; to reduce it to linear, you can do

sa = set(a)
[i for (i, v) in enumerate(out) if v not in sa]

.)

Upvotes: 3

Related Questions