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
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']))
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)
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)
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)
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
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']))
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)
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)
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)