31
votes

The return object is named None for list.reverse(). So this code fails when I call solution(k). Is there any way I can get around making a temporary? Or how should I do it?

fCamel = 'F'
bCamel = 'B'
gap = ' '

k = ['F', ' ', 'B', 'F']

def solution(formation):
    return ((formation.index(bCamel) > (len(formation) - 1 - (formation.reverse()).index(fCamel))))

p.s. This is my first code in python. I thought it was functional.

10
What happens if the elements you are looking for aren't in the list? Perhaps if you describe what you are trying to do we can help you make a better more "pythonic" solution. - GWW
I'm trying to solve that camel puzzle in python so I can learn the language a little. Basically, this function should return true if all the 'F's are on the left hand side of the first 'B'. - nakiya
Just wondering. I see more and more questions that remain without upvotes. This seems like an interesting question, if a simple one, to me. Why don't people vote for questions a bit more? I often see high volumes of votes for the replies, meaning that the question at least had the potential to bring interesting solutions or discussions, but not one vote for the questions itself. Seems odd to me (O_O) Cheers! - Morlock
@Morlock: I often wonder that too, I always try to up vote any interesting question. - GWW
list.reverse does not return list. That's a fact. What's your question? - S.Lott

10 Answers

32
votes

You can use reversed(formation) to return a reverse iterator of formation. When you call formation.reverse() it does an in place reversal of the list and returns None.

EDIT:

I see what you are trying to do now, in my opinion it's easier to just do this with a list comprehension:

def solution(formation):
    return len([k for k in formation[formation.index(bCamel)+1:] if k == fCamel]) == 0

This basically looks at all the elements after the first bCamel and collects all the elements that have the value fCamel. If that list has a length == 0 you have a solution.

Here's a few examples:

>>> k = ['F','F','B','B','F']
>>> solution(k)
False
>>> k = ['F','F','B','B','B']
>>> solution(k)
True
>>> k = ['F','F','B','F','F','B','B']
>>> solution(k)
False
>>> 
38
votes

You can use slicing to return the reversed list:

l[::-1]
8
votes

To build on GWW's answer, if you want this code to work as is you would just do list(reversed(formation)). If you really want to be able to use formation.reverse() instead, you would have to subclass list:

>>> class ReversableList(list):
...     def reverse(self):
...         return list(reversed(self))
... 
>>> x = ReversableList([1,2,3])
>>> x.reverse()
[3, 2, 1]

Whether or not this is advisable is another question of course.

4
votes

list.reverse reverses inplace. That is:

>>> l = [1, 2, 3]
>>> l.reverse()
>>> l
[3, 2, 1]

Please consult the Python documentation, things like these are laid out there. You can also try the 'help' built-in:

help(l.reverse) Help on built-in function reverse:

reverse(...) L.reverse() -- reverse IN PLACE

3
votes

I just came across this problem and wanted to clarify some things for users new to python coming from a javascript background.

In javascript, a.reverse() reverses in place and also returns the array when called.

Javascript:

var a = [2, 3 ,4]
console.log(a.reverse())
// outputs [4, 3, 2]
console.log(a)
// outputs [4, 3, 2]

In python, a.reverse() reverses in place, but does not return the array. This is what caused confusion for me.

In python:

a = [2, 3, 4]
a.reverse()
print(a)
# outputs [4, 3, 2]
# can't do print(a.reverse())
1
votes

the following changes will be effective:

NumSet={1,2,3,4,5,6,7,8,9,10}
NumList = list(NumSet)
NumList.reverse()
print(NumList)
  • avoid using the assignment operator after the initial assignment as lists are mutable types.

  • Using = operator with a method..(eg NumList = NumSet.reverse()) will cause the method to overwrite list with a blank, thereby effectively clearing the list. That's why list becomes a NoneType. Methods are functions and doesn't actually have its own value, thus the blank.

0
votes

Not super beautiful, but I did not find the equivalent in the precedent answers. If the speed or memory costs are low (the list is not very long or the operation not repeated a huge amount of times), this is pretty straight forward and even easier to read.

import copy

fCamel = 'F'
bCamel = 'B'
gap = ' '

k = ['F', ' ', 'B', 'F']

def solution(formation):
    rev_formation = copy.copy(formation)
    rev_formation.reverse()
    return ((formation.index(bCamel) > (len(formation) - 1 -
            (rev_formation).index(fCamel))))

Cheers

0
votes

This doesn't provide a solution to the F _ B F pattern problem, but it does address the issue of python not returning a list when you use .reverse().

This is how I got around it:

chars = ['a', '-', 'c']
chars2 = [] + chars
chars2.reverse()
totalChars = chars + chars2

totalChars returns a-cc-a, which is what I wanted, AND chars2 is a list, not a pointer to chars. Hope this helps.

0
votes

I don't know if this works for you, but this works for me:

list = [1,2,3]
print([list, list.reverse()][0])

The reason list.reverse() returns None is because the function doesn't return anything.

Using your code:

fCamel = 'F'
bCamel = 'B'
gap = ' '

k = ['F', ' ', 'B', 'F']

def solution(formation):
    return ((formation.index(bCamel) > (len(formation) - 1 - ([formation, formation.reverse()][0]).index(fCamel))))

print(solution(k))

Hope this works for you!

ps. Honestly, I have no idea why this works. I stumbled on it accidentally.

0
votes

Title question is already answered, but for what you were really after:

Basically, this function should return true if all the 'F's are on the left hand side of the first 'B'

That's the same as there's no 'B' followed by an 'F'. Nice way to check this is with an iterator:

def solution(formation):
    it = iter(formation)
    return not (bCamel in it and fCamel in it)

Some advantages:

  • Unlike every formation.index(...) solution it doesn't crash if the searched value isn't there.
  • Takes only O(1) extra space (unlike the solutions making a reversed copy of the list).
  • Touches every element at most once and stops as soon as possible. Even has O(1) time best case (even with millions of elements, if the list starts with ['B', 'F', then it stops right there).