1

I'm coming from an R background and am confused about the following:

Suppose I had "hello" in list format saved in the variable txt. Thus

 txt=  ['h','e','l','l','o']

After some testing, the following works:

txt.reverse()
"."join(txt)

and produces as expected olleh.

However, the following does not work:

"".join(txt.reverse())

It gives an error. I'm curious why that is the case as I thought I can "nest" function calls within function calls?

Thank you for helping!

8
  • 2
    You could use reversed instead: "".join(reversed(txt)). Commented Oct 16, 2013 at 20:25
  • @roippi reversed is in-place. Try reversed([1,2,3]) on the interpreter, it returns a listreverseiterator object which means no copies are made. The difference is that .reverse() modifies the original list, while reversed() iterates over it. Commented Oct 16, 2013 at 20:28
  • @Bakuriu yep. Haven't had my coffee today. "in place" (or the inverse) is a bad description for any sort of iterator. Commented Oct 16, 2013 at 20:29
  • @Bakuriu That just means reversed returns an iterator that will return the items in reverse order. It does not modify the original argument, which the reverse method does. Commented Oct 16, 2013 at 20:29
  • 1
    @viddhart - Here is an explanation: stackoverflow.com/questions/5317817/python-in-place-functions Commented Oct 16, 2013 at 23:31

5 Answers 5

5

The problem is that the reverse() function does not return an useful value (it returns None), because it reverses the list in-place, as a way to avoid the need to create a new output list. So this:

"".join(txt.reverse())

... Will try to join None, which clearly will fail.

Sign up to request clarification or add additional context in comments.

Comments

5

Being an in-place function, the reverse method of a list always returns None:

>>> a = [1, 2]
>>> print a.reverse()
None
>>> a
[2, 1]
>>>

You can get the behavior you want by using the reversed built-in:

>>> a = ['a', 'b']
>>> "".join(reversed(a))
'ba'
>>> a
['a', 'b']
>>>

3 Comments

Maybe also show the unmodified value of a in the reversed example, as you did the modified value of a in the reverse one?
Awesome, this is EXACTLY what was confusing me. In R, it's pretty much always an object that's returned, so I never had to worry about it. Makes complete sense. Thank you again.
@user1357015 In python operations that have side-effects usually do not return a value(i.e. they return None). Conversely, functions that return a value usually do not have side-effects. It's a convention used pretty often. By the way: you can always obtain R behaviour using some ors: "".join(txt.reverse() or txt). txt.reverse() returns None, which is considered false, so python will evaluate txt and return it instead(return values of or and and need not be booleans). However this seems quite dirty.
3

your problem is that txt.reverse() does NOT return the reversed list, it returns None,

ie, txt.reverse() reverses your list in place

Comments

2

You can use reversed instead:

".".join(reversed(txt))

Comments

1

As already said the list.reverse() replaces the list in-place, thus returns None

If you want a nestable version you can use the reversed function

In [7]: "".join(reversed(txt))
Out[7]: 'olleh'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.