# Composition of functions

Discussion in 'Python' started by Mladen Gogala, Jul 1, 2010.

If I write things with the intermediate variables like below, everything
works:

>>> x="quick brown fox jumps over a lazy dog"
>>> y=list(x)
>>> y

['q', 'u', 'i', 'c', 'k', ' ', 'b', 'r', 'o', 'w', 'n', ' ', 'f', 'o',
'x', ' ', 'j', 'u', 'm', 'p', 's', ' ', 'o', 'v', 'e', 'r', ' ', 'a', '
', 'l', 'a', 'z', 'y', ' ', 'd', 'o', 'g']
>>> y.reverse()
>>> y

['g', 'o', 'd', ' ', 'y', 'z', 'a', 'l', ' ', 'a', ' ', 'r', 'e', 'v',
'o', ' ', 's', 'p', 'm', 'u', 'j', ' ', 'x', 'o', 'f', ' ', 'n', 'w',
'o', 'r', 'b', ' ', 'k', 'c', 'i', 'u', 'q']
>>> z=''.join(y)
>>> z

'god yzal a revo spmuj xof nworb kciuq'

That is all well and kosher. Now, if I try to shorten things up, I will
get a type error:

>>> x="quick brown fox jumps over a lazy dog"
>>> y=''.join(list(x).reverse())

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError
>>>

Why is TypeError being thrown? The reason for throwing the type error is
the fact that the internal expression evaluates to None and cannot,
therefore, be joined:

>>> y=list(x).reverse()
>>> print y

None

And that is strange. From the example above, I saw that if I assigned the
intermediate array to hold list(x), did the reverse on that variable and
then did "join", everything works as advertised. Version of Python is
2.6.5 on Ubuntu 10. Why is the intermediate variable necessary?
I am a complete newbie and am trying the usual stuff, reversing strings,
displaying them in hex, writing things to file "test1.txt" and alike.
--

http://mgogala.byethost5.com

2. ### Stephen HansenGuest

On 6/30/10 8:50 PM, Mladen Gogala wrote:
>>>> x="quick brown fox jumps over a lazy dog"
>>>> y=''.join(list(x).reverse())

> Traceback (most recent call last):
> File "<stdin>", line 1, in<module>
> TypeError
>>>>

>

> Why is TypeError being thrown? The reason for throwing the type error is
> the fact that the internal expression evaluates to None and cannot,
> therefore, be joined:

The "reverse" method, like "sort" and a couple others, are in-place
operations. Meaning, they do not return a new list but modify the
existing list. All methods that are "in-place" modifications return None
to indicate this. This way you can't make a mistake and think its
returning a sorted / reversed copy but it isn't.

However, you can easily get what you want by using the 'reversed'
function (and similarly, the 'sorted' function), a la:

>>> y = ''.join(reversed(list(x)))

The 'reversed' and 'sorted' functions are generators that lazilly
convert an iterable as needed.

--

... Stephen Hansen
... Also: Ixokai
... Mail: me+list/python (AT) ixokai (DOT) io
... Blog: http://meh.ixokai.io/

Stephen Hansen, Jul 1, 2010

3. ### Chris RebertGuest

On Wed, Jun 30, 2010 at 9:09 PM, Zubin Mithra <> wrote:
> Hello,
>
>> >>> y=list(x).reverse()
>> >>> print y

>> None

>
>>>> L = ["a", "b", "c"]
>>>> L.reverse()
>>>> L

> ["c", "b", "a"]
>
> As you can see, L.reverse() performs the operation on itself and returns
> nothing. Hence, the return type None.
>
>
> y=''.join(list(x).reverse())
>
> you should probably do,
>
>>>> t = list(x).reverse()
>>>> y = ''.join(t)

Er, I don't think you thought that one entirely through (/ tried it out):

chris@morpheus ~ \$ python
Python 2.6.5 (r265:79063, May 25 2010, 18:21:57)
[GCC 4.2.1 (Apple Inc. build 5659)] on darwin
>>> x = "hello"
>>> t = list(x).reverse()
>>> print t

None
>>> ''.join(t)

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError

Cheers,
Chris
--
http://blog.rebertia.com

Chris Rebert, Jul 1, 2010

On Wed, 30 Jun 2010 21:04:28 -0700, Stephen Hansen wrote:

> On 6/30/10 8:50 PM, Mladen Gogala wrote:
>>>>> x="quick brown fox jumps over a lazy dog"
>>>>> y=''.join(list(x).reverse())

>> Traceback (most recent call last):
>> File "<stdin>", line 1, in<module>
>> TypeError
>>>>>
>>>>>

>>
>> Why is TypeError being thrown? The reason for throwing the type error
>> is the fact that the internal expression evaluates to None and cannot,
>> therefore, be joined:

>
> The "reverse" method, like "sort" and a couple others, are in-place
> operations. Meaning, they do not return a new list but modify the
> existing list. All methods that are "in-place" modifications return None
> to indicate this. This way you can't make a mistake and think its
> returning a sorted / reversed copy but it isn't.

Thanks.

>
> However, you can easily get what you want by using the 'reversed'
> function (and similarly, the 'sorted' function), a la:
>
> >>> y = ''.join(reversed(list(x)))

>
> The 'reversed' and 'sorted' functions are generators that lazilly
> convert an iterable as needed.

Ah, that is even better. Thanks.

--
http://mgogala.byethost5.com

5. ### Terry ReedyGuest

On 7/1/2010 12:32 AM, Mladen Gogala wrote:
> On Wed, 30 Jun 2010 21:04:28 -0700, Stephen Hansen wrote:

>> However, you can easily get what you want by using the 'reversed'
>> function (and similarly, the 'sorted' function), a la:
>>
>> >>> y = ''.join(reversed(list(x)))

>>
>> The 'reversed' and 'sorted' functions are generators that lazilly
>> convert an iterable as needed.

>
> Ah, that is even better. Thanks.

It is better if you do not mind making an unnecessary copy. If the list
had 10 million elements, you might prefer your original. And by the way,
sequential statements are a form of composition, even if strict
functionalists do not like to see it that way.

--
Terry Jan Reedy

Terry Reedy, Jul 1, 2010
6. ### Stephen HansenGuest

On 7/1/10 12:45 AM, Terry Reedy wrote:
> On 7/1/2010 12:32 AM, Mladen Gogala wrote:
>> On Wed, 30 Jun 2010 21:04:28 -0700, Stephen Hansen wrote:

>
>>> However, you can easily get what you want by using the 'reversed'
>>> function (and similarly, the 'sorted' function), a la:
>>>
>>> >>> y = ''.join(reversed(list(x)))
>>>
>>> The 'reversed' and 'sorted' functions are generators that lazilly
>>> convert an iterable as needed.

>>
>> Ah, that is even better. Thanks.

>
> It is better if you do not mind making an unnecessary copy. If the list

The original that did not work?

--

... Stephen Hansen
... Also: Ixokai
... Mail: me+list/python (AT) ixokai (DOT) io
... Blog: http://meh.ixokai.io/

Stephen Hansen, Jul 1, 2010
7. ### Paul RubinGuest

Paul Rubin, Jul 1, 2010
8. ### Wolfram HindererGuest

On 1 Jul., 06:04, Stephen Hansen <me+list/> wrote:
> The 'reversed' and 'sorted' functions are generators that lazilly
> convert an iterable as needed.

'sorted' returns a new list (and is not lazy).

Wolfram Hinderer, Jul 1, 2010
9. ### Stephen HansenGuest

On 7/1/10 5:29 AM, Wolfram Hinderer wrote:
> On 1 Jul., 06:04, Stephen Hansen<me+list/> wrote:
>> The 'reversed' and 'sorted' functions are generators that lazilly
>> convert an iterable as needed.

>
> 'sorted' returns a new list (and is not lazy).

Oops, you're right. Got the two crossed into one in my head.

--

... Stephen Hansen
... Also: Ixokai
... Mail: me+list/python (AT) ixokai (DOT) io
... Blog: http://meh.ixokai.io/

Stephen Hansen, Jul 1, 2010
10. ### MRABGuest

Zubin Mithra wrote:
>
> Er, I don't think you thought that one entirely through (/ tried it
> out):
>
>
> My Apologies.
>
> Here is a working one.
>
> >>> x="123"
> >>> t = list(x)
> >>> t.reverse()
> >>> print ''.join(t)

> 321
>
>
> But of course, the method which was suggested earlier is far more elegant.
>
> >>> print ''.join(reversed(list(x)))

>

If you want even more elegance, try slicing:

>>> x = "123"
>>> print x[ : : -1]

321

MRAB, Jul 1, 2010
11. ### Terry ReedyGuest

On 7/1/2010 3:54 AM, Stephen Hansen wrote:
> On 7/1/10 12:45 AM, Terry Reedy wrote:
>> On 7/1/2010 12:32 AM, Mladen Gogala wrote:
>>> On Wed, 30 Jun 2010 21:04:28 -0700, Stephen Hansen wrote:

>>
>>>> However, you can easily get what you want by using the 'reversed'
>>>> function (and similarly, the 'sorted' function), a la:
>>>>
>>>> >>> y = ''.join(reversed(list(x)))
>>>>
>>>> The 'reversed' and 'sorted' functions are generators that lazilly
>>>> convert an iterable as needed.
>>>
>>> Ah, that is even better. Thanks.

>>
>> It is better if you do not mind making an unnecessary copy. If the list

>
> The original that did not work?

The revised original that did work with sequential statements.

--
Terry Jan Reedy

Terry Reedy, Jul 2, 2010