Reputation: 9
For example:
foo = ["Bar", "Baz", "A", "F", ]
foo.sort().reverse()
or:
bar = "Foo bar baz was not very useful in the year seventeen ninety-three ".split()
bar.reverse().lower().title()
Is this allowed?
Upvotes: 0
Views: 59
Reputation: 13242
This has everything to do with which method you're using, and as mentioned, you have to know what the output of each method is.
This brings up the question? How can you know? There's always looking up the documentation online, but that can be time consuming and complicated. Python's, and most major module's creators, know this is an issue... so they've created good help()
documentation.
Given foo = ["Bar", "Baz", "A", "F", ]
Let's look at the output of help(foo.sort)
Help on built-in function sort:
sort(*, key=None, reverse=False) method of builtins.list instance
Sort the list in ascending order and return None.
The sort is in-place (i.e. the list itself is modified) and stable (i.e. the
order of two equal elements is maintained).
If a key function is given, apply it once to each list item and sort them,
ascending or descending, according to their function values.
The reverse flag can be set to sort in descending order.
We're interested in what the function returns. In this case, we can read it returns None
and does the sort in-place. We also find the reverse
flag I mentioned in a comment.
Let's look at help(foo.reverse)
Help on built-in function reverse:
reverse() method of builtins.list instance
Reverse *IN PLACE*.
Again, an inplace function, that isn't going to work if we chain something after it.
However, some of your other examples might work:
Given bar = "Foo bar baz was not very useful in the year seventeen ninety-three "
Let's look at help(bar.lower)
Help on built-in function lower:
lower() method of builtins.str instance
Return a copy of the string converted to lowercase.
It returns a copy, that can be chained.
What about help(bar.split)
?
Help on built-in function split:
split(sep=None, maxsplit=-1) method of builtins.str instance
Return a list of the words in the string, using sep as the delimiter string.
sep
The delimiter according which to split the string.
None (the default value) means split according to any whitespace,
and discard empty strings from the result.
maxsplit
Maximum number of splits to do.
-1 (the default value) means no limit.
It returns a list, so it can be chained, but we have to make sure that the chained method can be used on a list.
bar.split().lower()
outputs:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute 'lower'
Because lower
isn't a method that applies to a list.
If you want to apply a method to every element in a list, one simple way is using either list comprehension as shown by Samwise.
Or using map
like so:
>>> list(map(str.lower, bar.split()))
['foo', 'bar', 'baz', 'was', 'not', 'very', 'useful', 'in', 'the', 'year', 'seventeen', 'ninety-three']
Upvotes: 1
Reputation: 11
You can check the methods that is callable for a list by this :
foo = ["Bar", "Baz", "A", "F", ]
methods = [ method for method in dir(foo) if callable(getattr(foo, method)) ]
print(methods)
Upvotes: 0
Reputation: 71522
You can chain function calls, but you need to be aware of exactly what each function returns so that you can call a method on that object, or call a function that takes that object as an argument. sort()
doesn't return the list, it sorts the list in-place and returns None
. The same is true of reverse()
. None
isn't a list, so you can't call list methods on it.
The functions sorted()
and reversed()
, however, return new objects (sorted
returns a list, and reversed
returns an iterator that you can in turn convert into a list). So you can do:
>>> foo = ["Bar", "Baz", "A", "F", ]
>>> list(reversed(sorted(foo)))
['F', 'Baz', 'Bar', 'A']
Note that because these functions return new objects, the original foo
is unchanged:
>>> foo
['Bar', 'Baz', 'A', 'F']
For the example with bar
, you need to use a list comprehension in order to call the title()
method on each individual string:
>>> bar = "Foo bar baz was not very useful in the year seventeen ninety-three ".split()
>>> [i.title() for i in reversed(bar)]
['Ninety-Three', 'Seventeen', 'Year', 'The', 'In', 'Useful', 'Very', 'Not', 'Was', 'Baz', 'Bar', 'Foo']
Upvotes: 2