i is a variable. It is created by the for loop, and is set to the next word in the list, every time the loop is iterated. Aside from the first and last lines, this is a function. The way functions work, is they carry out a certain section of code, and you can do that many times (For example, do your chores, is a short way of saying take out the trash, mow the lawn, etc.). Functions can take in parameters(what is in the parentheses), so you can pass information into the function. As in the first example, putting n in the function parentheses is basically saying:
words = n
This is used so you can modify words without modifying the original input, so this function can be used for different purposes. The function in your example(join_strings), as implied in the name, joins two strings. No matter what you input, the output will be a combination of those two strings. For example:
result = ""
for i in range(len(words)):
result += words[i]
n = ["Michael", "Lieberman"]
print join_strings(n) #will return MichaelLieberman
t = ["Hello", "World"]
print join_strings(t) #will return HelloWorld
z = ["Does this make", " sense?"]
print join_strings(z) #will return Does this make sense?
Like I said, join_lists(m, n), basically is defining x and y, as m and n are being passed into the function, making x = m, and y = n