The Difference Between Calling List Methods Inside and Outside of a Print Function

Hi all. I’m a beginner in Python and trying to teach myself, so this might be a silly question.

I am confused about how to use class methods, particularly list methods (but this could apply to handling any class), and how they are called within a print function as opposed to outside of one.

family = ['Jason', 'Chris', 'Kellyn', 'Logan', 'Nolan']
print(family)
print(family.sort())
print(family)
print(family.pop())
print(family)

My question is basically, why does print(family.sort()) print None where print(family.pop()) prints the last name on the list? I would have expected the print function calling sort() to print a sorted list, like the pop() function prints the last name in the list while removing it.

Thank you for any assistance.

Let’s check the docs!

family.sort() is sorting the list in place. It doesn’t return the sorted list afterwards. If you used sorted(family) you’d get a new copy of the list in sorted order–the original list would be unchanged.

Meanwhile, pop is returning the thing it popped off the end of the list, so print(family.pop()) shows you the value.

It’s not crazy that list.sort() would return an additional reference to the same list, but (like the docs say) this can lead to later issues if people forget they have two references to the same list.

Side note: there’s no difference between being inside or outside of a print function (or any other function for that matter). They are called the same and act the same.

2 Likes

Reading this might help.

The main problem you are having is that list.sort() is not for returning the sorted list, but for sorting the list in place. It just returns None. To use it you have to do

family.sort()
print(family)

The function sorted would give you back the sorted list. With it you could do

print(sorted(family))

Thank you for the quick and detailed replies.

In trying to understand what is meant by “in place”, am I correct in thinking about it as pop() returns a value that isn’t the same as what went into the function (the input), where sort() takes the list as input, modifies it and returns None because it’s the same list, just modified?

Thank you for your time.

pop() modifies the object you passed it, removing one item, and returns that item.

sort() modifies the object you passed it, rearranging its contents, and returns None.

sorted() does not modify the object you passed it, and returns a rearranged copy of the object.

>>> var = [3,2,1]
>>> var.sort()
>>> var
[1, 2, 3]
>>> newvar = [5,6,4]
>>> sorted(newvar)
[4, 5, 6]
>>> newvar
[5, 6, 4]
>>> newvar.pop()
4
>>> newvar
[5, 6]

Okay, what seemed to help me understand better is actually playing around a bit more with the sort() function and some other ones, like remove(). It is actually unnecessary to return the modified list because the variable, family, refers to the modified list and you and just keep using that variable to refer to the list. If you want a new sorted list, use sorted().

After that I was able to actually sort the list and print it all on the same line like this:
print(f"{str(family.sort()).removeprefix('None')}{family}")

Thank you to everyone that helped train my brain for Python.

What you’re doing here is equivalent to

family.sort()
print(family)

But is far more convoluted and difficult to read. There’s no reason to keep things on one line [1]. It just makes your code harder to understand.

If you really want it on one line, use a semi-colon rather than going through the rigamarole of convert None to a string just to remove it:

family.sort(); print(family)

But still, don’t do this–there’s a reason the semi-colon is so rarely seen in Python.


  1. unless you’re playing code golf ↩︎

1 Like

Yes, I understand what you’re saying. I was just playing around and didn’t intend for this to be part of an actual program.

1 Like

That’s rather ridiculous. If you insist on something like that, do print(family.sort() or family). But don’t.

Well, that depends on the problem you’re trying to solve. If the problem you’re trying to solve is to sort and print a list all on the same line and don’t intend on others to read you code, or you have the proper comments, then that solves the problem.

James showed a more efficient way by using a semi-colon. I wasn’t aware of that, but I’m assuming that is not the preferred method.

Yes, James’s is very slightly more efficient. Mine just has the “advantage” of being more like yours and being one expression, so it can be used in more places. Generally preferred method is to use two lines.

Hello,

I will chime in.

You can also create a function so that the sorting step is done for you. This will allow you to make the sorting function call more cleanly as demonstrated below.

def sorted_list(some_list):
    some_list.sort()
    return some_list

print(f'This is my sorted list: {sorted_list(family)}')

This way, you don’t have to drag along the sorting step every time when printing the sorted list.

Or just use the builtin sorted function.

If you want to dive into “in-place modification”, mutability, and these topics, I find Ned Batchelder’s talk approachable: Facts and myths about Python names and values | Ned Batchelder

It’s both a website article and a PyCon talk.

4 Likes