range and len are both built-in functions. Since list methods are accepted, you could do this with insert. It is reeaallyy slow* but it does the job for small lists without using any built-ins:
def rev(l):
r = []
for i in l:
r.insert(0, i)
return r
By continuously inserting at the zero-th position you end up with a reversed version of the input list:
>>> print(rev([1, 2, 3, 4]))
[4, 3, 2, 1]
Doing:
def rev(l):
return l[::-1]
could also be considered a solution. ::-1 (:: has a different result) isn't a function (it's a slice) and [] is, again, a list method. Also, contrasting insert, it is faster and way more readable; just make sure you're able to understand and explain it. A nice explanation of how it works can be found in this S.O answer.
*Reeaaalllyyyy slow, see juanpa.arrivillaga's answer for cool plot and append with pop and take a look at in-place reverse on lists as done in Yoav Glazner's answer.
I've tried to google this but a lot of the answers I got were using old python versions.
groceries = ["apples", "bread", "milk", "eggs"]; groceries.reverse (); print (groceries)
Above is that obvious way to reverse the list but how would I go about doing that without the built in reverse function?
Could someone also explain to me how "the big-O" would have anything to do with this?
Edit: Essentially what I am trying to do is create a new function from scratch that takes my list and reverses it.
Edit 2:
Ok this is what I have so far, it doesn't work but maybe this will help you see what I am trying to do:
data_list = [1,2,"cat",4,"dog",6]
def backward(data_list):
length = len(data_list)
s = length
new_list = [None]*length
for item in data_list:
s = s - 1
new_list[s] = item
return new_list
data_rev = data_list.backward
print(data_list)
print()
print(data_rev)How to reverse a Python list (3 methods)
python - How do I reverse a list or loop over it backwards? - Stack Overflow
Why does [::-1] reverse a list?
Reversing a list in Python?
When should I use NumPy to reverse a list instead of native Python methods?
Are there any trade-offs between using built-in functions and manual methods to reverse a list?
How does slicing work when reversing a list?
Videos
range and len are both built-in functions. Since list methods are accepted, you could do this with insert. It is reeaallyy slow* but it does the job for small lists without using any built-ins:
def rev(l):
r = []
for i in l:
r.insert(0, i)
return r
By continuously inserting at the zero-th position you end up with a reversed version of the input list:
>>> print(rev([1, 2, 3, 4]))
[4, 3, 2, 1]
Doing:
def rev(l):
return l[::-1]
could also be considered a solution. ::-1 (:: has a different result) isn't a function (it's a slice) and [] is, again, a list method. Also, contrasting insert, it is faster and way more readable; just make sure you're able to understand and explain it. A nice explanation of how it works can be found in this S.O answer.
*Reeaaalllyyyy slow, see juanpa.arrivillaga's answer for cool plot and append with pop and take a look at in-place reverse on lists as done in Yoav Glazner's answer.
:: is not a function, it's a python literal. as well as []
How to check if ::, [] are functions or not. Simple,
import dis
a = [1,2]
dis.dis(compile('a[::-1]', '', 'eval'))
1 0 LOAD_NAME 0 (a)
3 LOAD_CONST 0 (None)
6 LOAD_CONST 0 (None)
9 LOAD_CONST 2 (-1)
12 BUILD_SLICE 3
15 BINARY_SUBSCR
16 RETURN_VALUE
If ::,[] were functions, you should find a label CALL_FUNCTION among python instructions executed by a[::-1] statement. So, they aren't.
Look how python instructions looks like when you call a function, lets say list() function
>>> dis.dis(compile('list()', '', 'eval'))
1 0 LOAD_NAME 0 (list)
3 CALL_FUNCTION 0
6 RETURN_VALUE
So, basically
def rev(f):
return f[::-1]
works fine. But, I think you should do something like Jim suggested in his answer if your question is a homework or sent by you teacher. But, you can add this quickest way as a side note.
If you teacher complains about [::-1] notation, show him the example I gave you.
There are three methods you can use to reverse a list:
An in-place reverse, using the built-in reverse method that every list has natively
Using list slicing with a negative step size, resulting in a new list
Create a reverse iterator, with the reversed() function
You can try this for yourself too. Click here to open a runnable/editable example.
To get a new reversed list, apply the reversed function and collect the items into a list:
>>> xs = [0, 10, 20, 40]
>>> list(reversed(xs))
[40, 20, 10, 0]
To iterate backwards through a list:
>>> xs = [0, 10, 20, 40]
>>> for x in reversed(xs):
... print(x)
40
20
10
0
>>> xs = [0, 10, 20, 40]
>>> xs[::-1]
[40, 20, 10, 0]
Extended slice syntax is explained here. See also, documentation.
Why would a double colon reverse a list? Is this something we just have to accept or is there some logic?
a = ['corge', 'quux', 'qux', 'baz', 'bar', 'foo'] print(a[::-1])
Hey, I'm learning lists in Python. When I try to use the reverse method to reverse my list it returns 'None'. I've read online that apparently this is because it doesn't actually change the list but I'm not sure what that means tbh. Even if it was a temporary modification, wouldn't it print that temporarily modified version of the list instead of printing 'None'? I found another solution (assuming the list is stored in my_list variable), print(my_list[::-1]). I understand that the -1 is referring to the end of the list (and maybe telling it to count back from there), but I have no idea what the '::' means. Would appreciate some help, thanks.
list[::-1]
I learned this years ago but never thought about it until reviewing just now. Why is it
[::-1]
? Does the first colon(:) mean we start at the beginning, and the second colon(:) mean we end also at the beginning?
newlist = oldlist[::-1]
The [::-1] slicing (which my wife Anna likes to call "the Martian smiley";-) means: slice the whole sequence, with a step of -1, i.e., in reverse. It works for all sequences.
Note that this (and the alternatives you mentioned) is equivalent to a "shallow copy", i.e.: if the items are mutable and you call mutators on them, the mutations in the items held in the original list are also in the items in the reversed list, and vice versa. If you need to avoid that, a copy.deepcopy (while always a potentially costly operation), followed in this case by a .reverse, is the only good option.
Now let's timeit. Hint: Alex's [::-1] is fastest :)
$ p -m timeit "ol = [1, 2, 3]; nl = list(reversed(ol))"
100000 loops, best of 3: 2.34 usec per loop
$ p -m timeit "ol = [1, 2, 3]; nl = list(ol); nl.reverse();"
1000000 loops, best of 3: 0.686 usec per loop
$ p -m timeit "ol = [1, 2, 3]; nl = ol[::-1];"
1000000 loops, best of 3: 0.569 usec per loop
$ p -m timeit "ol = [1, 2, 3]; nl = [i for i in reversed(ol)];"
1000000 loops, best of 3: 1.48 usec per loop
$ p -m timeit "ol = [1, 2, 3]*1000; nl = list(reversed(ol))"
10000 loops, best of 3: 44.7 usec per loop
$ p -m timeit "ol = [1, 2, 3]*1000; nl = list(ol); nl.reverse();"
10000 loops, best of 3: 27.2 usec per loop
$ p -m timeit "ol = [1, 2, 3]*1000; nl = ol[::-1];"
10000 loops, best of 3: 24.3 usec per loop
$ p -m timeit "ol = [1, 2, 3]*1000; nl = [i for i in reversed(ol)];"
10000 loops, best of 3: 155 usec per loop
Update: Added list comp method suggested by inspectorG4dget. I'll let the results speak for themselves.