Show the difference between Python's append() and extend() with both a list and a string.
append adds exactly one item to the end of the list. extend adds every element of the argument, one at a time. That single difference is the whole story.
a = [1, 2]
a.append([3, 4])
print(a) # [1, 2, [3, 4]] - one new element
b = [1, 2]
b.extend([3, 4])
print(b) # [1, 2, 3, 4] - the items are added
c = [1, 2]
c.append("hi")
print(c) # [1, 2, 'hi']
d = [1, 2]
d.extend("hi")
print(d) # [1, 2, 'h', 'i']The last two lines are the ones to explain. extend takes any iterable, and a string is an iterable of single characters, so extending with a string adds each letter as its own element. It is a common surprise, and the fix is to wrap the string in a list — d.extend(["hi"]) — or to use append when you want the string as a single item.
The nested-list case in the first two lines is worth dwelling on too. Appending a list gives you a list inside a list, which is often not what someone writing a.append(other_list) intends. When you want to copy the contents, extend is right; when you want to build a structure of lists, a list of lists is right, but then you should be explicit about it.
The performance note: extend with a list is more efficient than appending in a loop, because it copies the elements in one operation rather than reallocating the list's storage repeatedly.