0

I wrote this function to rotate a list to the left and it works fine except when I pass something like a [1,2,3,4], whose length is 1 - so ideally it should return None. How can I edit the code to fix this issue?

def rotate_left(list_of_elements):
    if len(list_of_elements) > 1:
        first_element = list_of_elements[0]
        for i in range(len(list_of_elements) - 1):
            list_of_elements[i] = list_of_elements[i+1]
        list_of_elements[-1] = first_element
        return list_of_elements

rotate_left([1,2,3,4],) gives [2,3,4,1]

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 1
    `f(x,)` calls f with the value `x`. It is not the same as `f((x,))` which calls it with the tuple `(x,)`. – interjay Jul 20 '23 at 15:29
  • If that's of any help, [`np.roll`](https://numpy.org/doc/stable/reference/generated/numpy.roll.html#numpy.roll) can handle this function for you! – alexis_thual Jul 20 '23 at 15:31
  • 1
    Why are you mentioning tuples when you deal with lists? And why should rotating a list of length 1 return None instead of itself? All this is very unclear to me. Your example does exactly what it's supposed to do, doesn't it? – Swifty Jul 20 '23 at 15:33
  • 1
    Are you open to alternate and simpler implementations? [Efficient way to rotate a list in python](https://stackoverflow.com/questions/2150108/efficient-way-to-rotate-a-list-in-python) – JonSG Jul 20 '23 at 15:34
  • 1
    One clarification, at the moment, `rotate_left([1])` does return `None`, but you seem to want that. What exactly is the problem you have? – JonSG Jul 20 '23 at 15:44
  • And so does `rotate_left(([1,2,3,4],))` – chrslg Jul 20 '23 at 15:55

2 Answers2

0

You can use list slicing to do list rotation. ls[1:] means all elements from position one to end. ls[0] is the first element. To rotate left, put first element to the last. You can use ls[1:] + [ls[0]] to join the lists. So the code becomes:

def rotate_left(ls):
    if len(ls) >= 2:
        return ls[1:] + [ls[0]]

To rotate right, put last element first, use ls[-1] to get last element, and ls[:-1] to get all elements before the last element.

def rotate_right(ls):
    if len(ls) >= 2:
        return [ls[-1]] + ls[:-1]

Output:

rotate_left([0, 1, 2, 3, 4])
#[1, 2, 3, 4, 0]

rotate_left([0, 1, 2, 3])
#[1, 2, 3, 0]

rotate_left([0, 1])
#[1, 0]

rotate_right([0, 1])
#[1, 0]

rotate_right([0, 1, 2])
#[2, 0, 1]

rotate_right([0, 1, 2, 3, 4])
#[4, 0, 1, 2, 3]

rotate_right([0])
#returns None

rotate_left([])
#returns None
Ξένη Γήινος
  • 2,181
  • 1
  • 9
  • 35
0

If what you were trying to do was pass it a tuple with one list inside, this was answered by @interjay in the comments but, you're not actually passing the function a tuple. For example:

list, # not a tuple, just a single list
(list,) # valid tuple with single list inside

More examples:

list # one list
list, # one list
(list) # also one list
(list,) # tuple with one list inside
(list, list) # tuple with two lists inside
(list, list,) # tuple with two lists inside

Also the function is written to accept a single list. If you pass it a tuple, you have to handle for a tuple.

Currently if you pass this function a tuple whose len is less than or equal to 1, it will return None; However if the tuple has more than one item inside, it will break:

your_function((item,)) # returns None since len is 1
your_function((item, item2)) # breaks program
your_function((item, item2,)) # breaks program

To fix this add a check to your function:

if (type(list_of_elements) != list): return

like this:

def rotated_left(list_of_elements):
    if (type(list_of_elements) != list): return
    if len(list_of_elements) > 1:
        print(len(list_of_elements))
        first_element = list_of_elements[0]
        for i in range(len(list_of_elements) - 1):
            list_of_elements[i] = list_of_elements[i+1]
        list_of_elements[-1] = first_element
        return list_of_elements

Things to remember

li = [1,2,3] # makes a list
tu = li, # makes a tuple with li
your_function(li,) # passes a list to your function
                   # does not make a tuple and pass it to your function
Nohj
  • 1
  • 4