Python Function List, Sublist Issue


#1

Hello! I am new to python and I am trying to create a function that accepts as input a list of lists of integers and returns a sorted version of that list, sorted by the sum of the integers in each sub-list. Below is the code I have thus far. Any suggestions would be great. Currently, I am getting NameError: name 'user_list' is not defined.

def sort_nested_lists(user_list):
   return sorted(user_list,key = sum)
print user_list

#2

You have defined user_list in the function, but it does not exist in global scope where your print statement is.

>>> sort_nested_lists([[5,2,7,5],[8,2,6,1],[3,1,8,9,5]])
[[8, 2, 6, 1], [5, 2, 7, 5], [3, 1, 8, 9, 5]]
>>> def sort_nested_lists(user_list):
   return sorted(user_list, key=sum, reverse=True)

>>> sort_nested_lists([[5,2,7,5],[8,2,6,1],[3,1,8,9,5]])
[[3, 1, 8, 9, 5], [5, 2, 7, 5], [8, 2, 6, 1]]
>>>

#3

Thanks for the feedback! So that makes sense, but now when I indent my print statement nothing actually execute. Any ideas?

def sort_nested_lists(user_list):
	return sorted(user_list,key = sum)
	print user_list

#4

Why would it print? The function exits before it gets there and besides, user_list is the original unsorted list. Call the function and print the result instead

also, write it like so instead: return sorted(user_list, key=sum) (PEP8 style suggestions)


#5

Anything after return is unreachable. Study the examples above. Create your list under any variable name, then pass the variable, and print the return value.

def foo(bar):
    return ...

list_of_lists = [[],[],[]]

print foobar(list_of_lists)

#6

I think I am getting closer...so I did not provide any data to user list so the function did not know where to grab input from. So I came up with a raw input strategy for the first line. However, the code is still not executing. I get the below error:

Please enter a list of integers: [[5,2,7,5],[8,2,6,1],[3,1,8,9,5]]

sort_nested_lists = raw_input("Please enter a list of integers: ")
def sort_nested_lists(user_list):
return sorted(user_list,key = sum)
print sort_nested_lists


#7

Consider what type raw_input returns and what type your function expects. Do those match?

Note that you could use the input function instead of raw_input, however I strongly suggest not doing so because it's equivalent to handing over control of the program to the person entering input (it's like a genie granting a wish, the user could wish for more wishes, or for something else that has nothing to do with what you meant for input to do)

Far better would be to write some code that creates a list that looks like the one described in the input string, at which point you'll probably protest that this is too hard. It's not.

There's a safer way to parse strings to lists though: https://docs.python.org/2/library/ast.html#ast.literal_eval


#8

Thanks for the suggestion. Good point raw_input was a string and I tried to convert it to an integer with the below code:

user_list = int(raw_input("Please enter a list of integers: "))
def sort_nested_lists(user_list):
   return sorted(user_list,key = sum)
print sort_nested_lists

Traceback (most recent call last):
File "test.py", line 1, in
user_list = int(raw_input("Please enter a list of integers: "))
ValueError: invalid literal for int() with base 10: '[[5,2,7,5],[8,2,6,1],[3,1,8,9,5]]'

I am not too concerned with if it's safe or not right now, but thanks for the link, I may revisit it in the future.


#9

The quotes are still there since a list cannot be converted to an integer. It is a string representation of a complex data structure. That is where the asp module method that @ionatan recommended comes in to help extract the true data type from the representation.

Without that module, one will have to come up with something that performs that same task. Failing that, a new approach is needed to get user data and construct the list from that data.

The user could for instance enter a comma separated list with no data structure. Then the program could split the input on the commas and convert the items in the list to integers. Repeat as many times as the user has additional lists (this is a list of lists problem, right?). Each new list would be appended to a running list which in the end would be passed to your function.

>>> a = raw_input("Enter a comma separated list of integers: ")
Enter a comma separated list of integers: 5,2,7,5
>>> a = a.split(',')
>>> a
['5', '2', '7', '5']
>>> a = [int(x) for x in a]
>>> a
[5, 2, 7, 5]
>>>

Or more succinctly,

>>> a = raw_input("Enter a comma separated list of integers: ")
Enter a comma separated list of integers: 5, 2, 7, 5
>>> a = [int(x) for x in a.split(',')]
>>> a
[5, 2, 7, 5]
>>>

Functionally speaking, we break this problem into small getter and setter utilities, starting with the basic inputs.

def get_user_int_list():
    a = input("Enter a comma separated list of integers: ")
    try:
        return [int(x) for x in a.split(',')]
    except ValueError:
        return "ValueError!"

This is only a demo, with verbosity disabled.

>>> list_of_lists = []
>>> list_of_lists.append(get_user_int_list())
Enter a comma separated list of integers: n,o,n,e
>>> list_of_lists
['ValueError!']
>>> list_of_lists.append(get_user_int_list())
Enter a comma separated list of integers: [1],[2],[3],[4]
>>> list_of_lists
['ValueError!', 'ValueError!']
>>>

This is just a sketch, mind; one that you can draw ideas from.