Понимание списка должно перебирать кортеж на уровне Python:
>>> dis.dis("[i for i in (1,2,3)]")
1 0 LOAD_CONST 0 (<code object <listcomp> at 0x1075c0c90, file "<dis>", line 1>)
2 LOAD_CONST 1 ('<listcomp>')
4 MAKE_FUNCTION 0
6 LOAD_CONST 5 ((1, 2, 3))
8 GET_ITER
10 CALL_FUNCTION 1
12 RETURN_VALUE
list
выполняет итерации по самому кортежу и использует C API для этого, не проходя (в значительной степени) модель данных Python.
>>> dis.dis("list((1,2,3))")
1 0 LOAD_NAME 0 (list)
2 LOAD_CONST 3 ((1, 2, 3))
4 CALL_FUNCTION 1
6 RETURN_VALUE
Итерация уровня Python более отчетливо видна в Python 2, который реализует списки в другом виде.
>>> def f():
... return [i for i in (1,2,3)]
...
>>> dis.dis(f)
2 0 BUILD_LIST 0
3 LOAD_CONST 4 ((1, 2, 3))
6 GET_ITER
>> 7 FOR_ITER 12 (to 22)
10 STORE_FAST 0 (i)
13 LOAD_FAST 0 (i)
16 LIST_APPEND 2
19 JUMP_ABSOLUTE 7
>> 22 RETURN_VALUE
Как указывает @blhsing, вы можете разобрать объект кода, сгенерированный списком в Python 3, чтобы увидеть то же самое.
>>> code = compile('[i for i in (1,2,3)]', '', 'eval')
>>> dis(code.co_consts[0])
1 0 BUILD_LIST 0
2 LOAD_FAST 0 (.0)
>> 4 FOR_ITER 8 (to 14)
6 STORE_FAST 1 (i)
8 LOAD_FAST 1 (i)
10 LIST_APPEND 2
12 JUMP_ABSOLUTE 4
>> 14 RETURN_VALUE