Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialRobert Peters
3,728 PointsHow do I improve this function?
I've made a function that reorders a list, and I'm wondering if there's an easier/better way to do it?
It takes an argument that would be a user input string of numbers representing the new list item order, such as: "1,4,2,5,3". It then strips the commas and splits it into a list such as ["1", "4", "2", "5", "3"] so that it can be looped through.
Note: I used copy.copy() to make changes to a copy of the list within the loop, then updated the main list to the copy at end, otherwise the items ended up in the wrong order for some reason!
Here's the code:
import copy
current_lists = [ {'test1':[]}, {'test2':[]}, {'test3':[]}, {'test4':[]}, {'test5':[]} ]
def reorder_lists(new_list_position):
split_list = new_list_positions.split(",")
working_list = copy.copy(current_lists)
count = 0
for item in split_test:
item_to_insert = current_lists[int(item) - 1]
working_list.remove(item_to_insert)
working_list.insert(count, item_to_insert)
count += 1
current_lists = working_list
So if run with:
test_user_input = "1,4,2,5,3"
reorder_lists(test_user_input)
print(current_lists)
it shows: [ {'test1':[]}, {'test4':[]}, {'test2':[]}, {'test5':[]}, {'test3':[]} ]
4 Answers
Jeff Muday
Treehouse Moderator 28,720 PointsOk-- I get what you are looking for. Megan's suggestion of the enumerate function is a good one.
If you need this to fit a "functional programming paradigm" you would not want to reference a global variable in the function and be aware that the programmer could pass an immutable list so you would always want to create a new list.
current_list = ["test1", "test2", "test3", "test4", "test5"]
user_input = "5,3,1,4,2"
def reorder_list(user_list, user_order):
sorted_list = user_list[:]
for idx, item in enumerate(user_order.split(",")):
sorted_list[idx] = user_list[int(item)-1]
return sorted_list
print("Before")
print(current_lists)
sorted_list = reorder_list(current_list, user_input)
print("After")
print(sorted_list)
or if you a masochist, you can do this as a list comprehension in one line! Definitely not Pep20 inspired.
sorted_list = [current_list[i] for i in [int(x)-1 for x in user_input.split(',')]]
Jeff Muday
Treehouse Moderator 28,720 PointsDo you mean something like this?
test_user_input = "1,4,2,5,3"
# create a new list based on the split string.
newlist = test_user_input.split(',')
# sorting in-place
newlist.sort()
print(newlist)
# can also sort in the reverse direction
newlist.sort(reverse=True)
print(newlist)
Robert Peters
3,728 PointsThanks Jeff, but I meant that the user input is the order that they want the items of the list to be. I think I complicated it by having dicts in the list, but if a list was: ["test1", "test2", "test3", "test4", "test5"] And the user input was "5,3,1,4,2", then the list would be changed to: ["test5", "test3", "test1", "test4", "test2"]
Megan Amendola
Treehouse TeacherInstead of using a count, you could instead use enumerate to get both an index and the item in your iterable.
for count, item in enumerate(split_test):
item_to_insert = current_lists[int(item) - 1]
working_list.remove(item_to_insert)
working_list.insert(count, item_to_insert)
Robert Peters
3,728 PointsThanks Megan, I'll look into enumerate now!
Jeff Muday
Treehouse Moderator 28,720 PointsJust in case you were looking to sort the dictionary objects that had list strings.
current_lists = [{'test1':'4,6,3,1'}, {'test2':'9,3,2,1'}]
def reorder_lists_alt(user_lists, reverse=False):
sorted_lists = []
for obj in user_lists:
if not isinstance(obj, dict):
continue
for key, lst in obj.items():
if isinstance(lst, str):
newlist = lst.split(',')
newlist.sort(reverse=reverse)
sorted_lists.append({key:newlist})
return sorted_lists
print("Before")
print(current_lists)
sorted_lists = reorder_lists_alt(current_lists)
print("After")
print(sorted_lists)
print("Reversed lists")
sorted_lists_reversed = reorder_lists_alt(current_lists, reverse=True)
print(sorted_lists_reversed)
Before
[{'test1': '4,6,3,1'}, {'test2': '9,3,2,1'}]
After
[{'test1': ['1', '3', '4', '6']}, {'test2': ['1', '2', '3', '9']}]
Reversed lists
[{'test1': ['6', '4', '3', '1']}, {'test2': ['9', '3', '2', '1']}]
Robert Peters
3,728 PointsThis is pretty useful for the future, cheers!