А зачем тебе вообще что-то кроме самого списка? Все встроенные коллекции (list, dict, set) уже являются потокобезопасными. Это значит, что если у тебя в список [1, 2] два потока примерно в одно время попытаются добавить 3 и 4 соответственно, то результирующий список будет [1, 2, 3, 4] или [1, 2, 4, 3]. Никуда ничего не пропадёт.
Другое дело, что код, который ты привёл, не дожидается конца выполнения потока.
from threading import Thread
l = []
def target(x):
l.append(x**2)
threads = []
for i in range(10):
t = Thread(target=target, args=(i, ))
t.start()
threads.append(t)
for t in threads:
t.join()
print(l)
Но я бы задумался о том, зачем тебе такой код. Пока он выглядит костыльно. Есть куда более высокоуровневые штуки вроде
ThreadPoolExecutor