0

I think I have a rather simple question, however, it has me stumped.

All I need to do is insert something to a list like so:

list = ["apples", "oranges", "more apples"]
list.insert(10, "pears")

Without resulting in this:

["apples", "oranges", "more apples", "pears"]

There need to be a number of empty spaces for the indexes 4 to 9, much like in Lua or Ruby with the nil value. I could use a for-loop to fill the gap, however, I would have trouble iterating over it and inserting into the beginning of the list (because it would shove everything else to the side). Any thoughts are appreciated!

Keto Z
  • 49
  • 1
  • 7
  • I think a for loop would work, not sure why it wouldn't. Can you please explain why wouldn't it work? I don't really understand this, "I would have trouble iterating over it and inserting into the beginning of the list (because it would shove everything else to the side)". – TheNavigat Jul 20 '17 at 12:43
  • Possible duplicate of [Python List - "reserving" space ( ~ resizing)](https://stackoverflow.com/questions/8849833/python-list-reserving-space-resizing) – Tezirg Jul 20 '17 at 12:44
  • Possible duplicate of [sparse assignment list in python](https://stackoverflow.com/questions/1857780/sparse-assignment-list-in-python) – Chris_Rands Jul 20 '17 at 12:44
  • Possible duplicate of [Python list set value at index if index does not exist](https://stackoverflow.com/questions/22388866/python-list-set-value-at-index-if-index-does-not-exist) – EarthDragon Jul 20 '17 at 12:45
  • @TheNavigat It is a list of objects, and later on, I iterate through (on several occasions) to see what the object.property is. So, with every time I iterate through, I would have to have a try/except statement. For the insertion issue, we would have something like [1, 2, 3, 0, 0, 6]. If I want to list.insert(4, 4) I would shove the value 6 into 7's place. – Keto Z Jul 20 '17 at 12:48

4 Answers4

1

You'll need to pad the list.

def padded_insert(lst, at_idx, value):
    if len(lst) <= at_idx:
        npads = at_idx - len(lst) + 1
        lst += [ None ] * npads # or '' or 0 or whatever...
    lst[at_idx] = value
aghast
  • 14,785
  • 3
  • 24
  • 56
  • 1
    This will overwrite existing values in `at_idx` is smaller than the length, whereas `insert` would usually not do that. – tobias_k Jul 20 '17 at 12:47
1

Have you consider switching to a dictionary and use the index as its key?

dict = {1: 'apples',
        2: 'oranges',
        3: 'more apples'}
dict[10] = 'pears'

so dict will be:

{1: 'apples', 2: 'oranges', 3: 'more apples', 10: 'pears'}

IMHO, I don't think you need a list to achieve your purpose.

0

Here:

def insert_with_pad(arr, index, val):
    if len(arr) <= index:
        pad_length = index - len(arr)
        arr = arr + ['' for i in range(pad_length)] + [val]
    else:
        # No need to pad
        arr[index] = val

    return arr

Input:

insert_with_pad(['a', 'b'], 3, 'w')

Output:

['a', 'b', '', 'w']
dheiberg
  • 1,914
  • 14
  • 18
0

A small function I made for this:

def insert(item, pos, lst):
    if pos > len(lst):
        return lst+[None]*(pos-len(lst))+[item]
    else:
        lst.insert(pos, item)
        return lst

But for just a one line thing you could just use:

pos = 10
item = pears

lst += [None]*(pos-len(lst))+[item]

which would work only if the index was greater than the length of the list. Or a messy way of doing it would be:

if pos>len(lst): lst+=[None]*(pos-len(lst))+[item]
else: lst.insert(pos, item)
56-
  • 556
  • 5
  • 11