list index out of range error when sorting a list

Question:

so i am trying to sort a list of members by their ‘id’ in a new list. the problem is that python tells me that the index is out of range which i don’t understand since i do have a value at that index spot in the list.

here my code

members = [
  {'id': 1, 'firstname': 'johnny', 'lastname': 'doe'    },
  {'id': 3, 'firstname': 'sky',    'lastname': 'smith'  },
  {'id': 4, 'firstname': 'mary',   'lastname': 'johnes' },
  {'id': 2, 'firstname': 'frank',  'lastname': 'sanchez'}
]

NewMembers = []
i = 0
ids = 1

while len(NewMembers) != len(members):
    if ids == members[i]['id']:
        NewMembers.append(members[i])
        ids += 1
    else:
        i += 1

print(NewMembers)

output

line 8, in <module>
if ids == mymembers[i]['id']:
          ~~~~~~~~~^^^
IndexError: list index out of range
Asked By: Johnny garcia

||

Answers:

Consider your logic with your sample. It will only work if the IDs are already sorted. Otherwise i will continue to be incremented until an out of bounds access occurs.

You should be using sorted which allows you to specify a key to sort on. In this case a lambda that returns the id of each element.

print(sorted(members, key=lambda x: x['id']))
Answered By: Chris

If you want to use a lambda expression:

NewMembers = members.copy()
NewMembers.sort(key=lambda member : member['id'])

If you don’t want to use lambdas:

def getID(member):
    return member['id']

NewMembers = members.copy()
NewMembers.sort(key=getID)
Answered By: buffman23

If You wanna select people with specific id You can use the code below:

members = [{'id': 1, 'firstname': 'johnny', 'lastname': 'doe'},{'id': 3, 'firstname': 'sky', 'lastname': 'smith'},{'id': 4, 'firstname': 'mary', 'lastname': 'johnes'},{'id': 3, 'firstname': 'frank', 'lastname': 'sanchez'}]

NewMembers = []
i = 0
ids = 1
while i != len(members):
    if ids == members[i]["id"]:
        NewMembers.append(members[i])
    i += 1

print(NewMembers)
Answered By: aljustiet

Yes you have a value, but it became too big
At one moment your cycle is reaching i>3, that means it is trying to get

if ids == members[4]['id']

So this is out of range of your values

If you want to use cycle, much better to use "for". Here’s how:

members = [{'id': 1, 'firstname': 'johnny', 'lastname': 'doe'},{'id': 3, 'firstname': 'sky', 'lastname': 'smith'},{'id': 4, 'firstname': 'mary', 'lastname': 'johnes'},{'id': 3, 'firstname': 'frank', 'lastname': 'sanchez'}]

new_members = []
max_difference = 0

for m in members:
    if m['id'] > max_difference: max_difference = m['id']

for n, member in enumerate(members):
    if n == 0:
        new_members.append(members[n])
        continue

    right_i = -1
    left_i = -1
    duplicate = -1
    right_difference = -max_difference
    left_difference = max_difference
    for i, new_member in enumerate(new_members):

        if (
            abs(new_member['id'] - member['id']) == new_member['id'] - member['id']
            and
            right_difference < new_member['id'] - member['id']
            ):
            right_difference = new_member['id'] - member['id']
            right_i = i
        elif (
            abs(new_member['id'] - member['id']) != new_member['id'] - member['id']
            and
            left_difference > new_member['id'] - member['id']
            ):
            left_i = i
        elif new_member['id'] - member['id'] == 0:
            new_members.append(members[n])
            duplicate = i
            break

    if duplicate != -1: new_members.insert(duplicate, members[n])
    elif left_i != -1: new_members.insert(left_i+1, members[n])
    else: new_members.insert(right_i, members[n])
            

print(new_members)

Not the most beautiful sorting algo, but uses only cycles and works 100% with any amount of input
(if id is integer)

Answered By: Nikolay Baakh
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.