I found this code on the web, and i have been reading it 100times but i
do not get it. It makes no sence…
This is partly why we like code to come with comments.
i’ve tried to print(i), print(left_node) etc to see what happens at
each step.
A good approach. I’d be inclined to:
print(i, left_node, current_node, right_node)
in one go to easily see how they’re grouped.
I also now trying to understand the difference between (), and . I’ve understood or seen the difference between the usage of these two before but forgot.
Square brackets do 2 things in Python:
- define a list
- index an object (for example a list or a dict)
With some object to the left, it is the indexing operation:
li[i]
Here li
is the object being indexed and i
is the index used to get
something out of li
.
Without something to the left, we’re defining a list:
li = [100, 78, 98, 62, 54, 36, 145]
There’s no object to the left of the [
(between the =
and the [
).
Round brackets do 3 things in Python:
- grouping in expressions
- calling functions (or methods - any callable)
- syntactly defining a context which defines a tuple;
technically the brackets are not part of the tuple syntax, they’re
just grouping again 
Grouping in expressions when operation order from the default precedence
is not the desired order. Eg:
twenty_three = 8 + 3 * 5
fifty_five = (8 + 3) * 5
Calling functions. Again, with an object (the callable) to the left:
res.append(current_node)
Here, res.append
is the list
type’s append
method, bound to the
res
object. So that res.append
becomes a function which appends to
res
. Then you call res.append
with current_node
. And the brackets
after the object (res.append
) cause the call.
So now we have:
indexable_object[index]
callable_object(argument_value)
Tuples: you will often see:
x = (1, 2, 3)
Here’s we’ve defines a 3-tuple with values 1
, 2
and 3
. A tuple is
effectively a read-only list
: you cannot change its values after
you’ve made it. For example, you can’t .append
to a tuple. But you can
index it, for example.
Note: here, the brackets are not part of the tuple syntax. They’re
just grouping. This means the same thing:
x = 1, 2, 3
The brackets are only requires where (precedence again) the expression
would mean something else. Example:
print(1, 2, 3)
Here we’re calling the print()
function with 3 arguments. But if we
wanted to print a tuple we’de write:
print( (1, 2, 3) )
The brackets group the 1,2,3
together as a tuple and are needed
because the precedence of the comma between function arguments is higher
than the precedence of a comma making a tuple. So in function arguments
the 1,2,3
is 3 arguments. Using brackets for the argument makes it one
argument, which is a tuple.
i cant understand how the the -2 in the for loop works with the len func → for i in range(len(li)-2)
then the: → current_node = li[i + 1] and right_node = li[i+2]
Let’s look at the code:
li = [100, 78, 98, 62, 54, 36, 145]
res = []
for i in range(len(li)-2):
left_node = li[i]
current_node = li[i + 1]
right_node = li[i+2]
if current_node < left_node and current_node < right_node:
res.append(current_node)
print(res)
I’ve aligned the if-statement with the other statements in the loop
body.
We define a list li
of the numbers you want to examine, and an empty
list res
which will accrue the result numbers.
Let’s look at the loop body first:
left_node = li[i]
current_node = li[i + 1]
right_node = li[i+2]
This picks 3 adjacent values form the list li
at positions i
, i+1
and i+2
. If the middle of those 3 elements is less than the elements
beside it, it gets added to the res
list:
if current_node < left_node and current_node < right_node:
res.append(current_node)
Now let’s look at the loop. If we want to examine all the 3-element
subspans of the list, we need to start at indices 0
, 1
and 2
(i.e.
when i
is 0
) and end with the rightmost index being the last index
in the list (i.e. 6
for your example list).
Because indices in Python count from 0
, the last index is len(li)-1
i.e. 6
because you have a 7 element list.
The range(n)
function returns values from 0
though n-1
, just like
the list indices for a list of length n
. So typically you’d use it as
range(len(li))
:
for i in range(len(li)):
print(li[i])
However, inside the loop you access not just index i
, but also i+1
and i+2
. So you need your range to count 2 fewer places to prevent
i+2
being off the end of the list. That is why this loop uses
range(len(li)-2)
.
Cheers,
Cameron Simpson cs@cskk.id.au