Home > Back-end >  Python inserting in an empty list at specific index doesn't work
Python inserting in an empty list at specific index doesn't work

Time:05-04

I have a list of object, each object contains a unique ID. The current list is like so:

[{"id": 3}, {"id": 5}, {"id": 8}]

I want to change the indexes a bit - instead of the dictionary with id = 3 to be on index 0, I want the dictionary with id = 3 to be on index 3.

I have tried:

list = []
for item in items:
    list[item["id"]] = item

but that gives me indexing error. Then I tried to do the following:

list = []
for item in items:
    list.insert(item["id"], item)

which just acts like a regular append (does not insert at specified index).

I have a last ditch attempt to do this on the front end when I am getting the response from the API but that defeats the whole purpose of reducing the amount of looping I do on the client side. The reason being is that the server can knock out these loops in like 50 milliseconds and on the client side it takes up to 300 milliseconds since it runs in the browser.

CodePudding user response:

There is no problem in your code it all happens because your list has zero element

items = [{"id": 3}, {"id": 5}, {"id": 8}]
list_ = []
for item in items:
    while item['id'] > len(list_):
        list.append(None)
    list_.insert(item["id"], item)
print(list_)

OUTPUT:

You can see here your elements are inserted inside the list.

[None, None, None, {'id': 3}, None, {'id': 5}, None, None, {'id': 8}, None]

The above code works perfectly if the dictionary inside the list is in increasing order, But if the dictionary is in random order then first you need to first change the list to increasing order.


items = [{"id": 3}, {"id": 5}, {"id": 8},{'id':2}]
items = (sorted(items,key=lambda e:e['id'])) # sort the list
list_ = [] 
for item in items:
    while item['id'] > len(list_):
        list.append(None)
    list_.append(item)
print(list)

INPUT/OUTPUT

IN:items = [{"id": 3}, {"id": 5}, {"id": 8},{'id':2}]

OUTPUT FROM FIRST ANSWER:[None, None, {'id': 2}, None, {'id': 3}, None, {'id': 5}, None, None, {'id': 8}]

OUTPUT FROM SECOND ANSWER:[None, None, {'id': 2}, {'id': 3}, None, {'id': 5}, None, None, {'id': 8}]

CodePudding user response:

I think the general solution for this will be

a= [{"id": 3}, {"id": 5}, {"id": 8}]
l = [None for _ in range(max(a,key=lambda x: x["id"])["id"] 1)]
for item in a:
    l[item["id"]]= item
print(l)

Also insert and item assignment is creating error because it expects that index to be exist beforehand so in that case you need to initialize your list with empty labels

CodePudding user response:

Create an empty list with needed indexes first like

data = [{"id": 3}, {"id": 5}, {"id": 8}]
mod_list = [None]*max(x.get("id") for x in data)

Now fill the indexes with needed data

[mod_list.insert(x.get("id"),x) for x in data]

You get a list like this

[None, None, None, {'id': 3}, None, {'id': 5}, None, None, {'id': 8}, None, None]

The None indexes can be ignored in processing.

CodePudding user response:

You can't insert into an empty list at index 3. The first element you add to a list will always be at index 0. More general, you can't insert at an index that's higher than the list is long. If you want a quick way to look up items with a specific index, use another dict instead of a list as the container:

>>> lst = [{"id": 3}, {"id": 5}, {"id": 8}]
>>> d = {x["id"]: x for x in lst}
>>> d
{3: {'id': 3}, 5: {'id': 5}, 8: {'id': 8}}
>>> d[3]
{'id': 3}

This way, each element can be looked up in O(1) using its ID as the index. And this will also work if the IDs are very large numbers (when its impractical to create a mostly empty list with that many indices) or even non-numeric, e.g. strings.

CodePudding user response:

You can do below steps;

x = [{"id": 3}, {"id": 5}, {"id": 8}]
    
x.insert(3, x[0])
del x[0]
  • Related