Из документации Python :
keys ()
Возвращает новый вид ключей словаря. См. документацию по объектам вида .
и по ссылке выше:
Объекты, возвращаемые dict.keys (), dict.values () и dict.items () являются объектами просмотра. Они обеспечивают динамическое представление c для записей словаря, что означает, что когда словарь изменяется, представление отражает эти изменения.
Представления словаря могут быть перебраны для получения соответствующих данных и поддержки тестов членства [ ...]
Без keys () - метод, у вас есть просто итератор по доступным ключам (что, вероятно, предпочтительнее), как вы можете видеть здесь (то же, что и second, но без загрузки и метод вызова ключей):
In [1]: import dis
In [2]: dis.dis("for i in {None: None}: print(i)")
1 0 LOAD_CONST 0 (None)
2 LOAD_CONST 0 (None)
4 BUILD_MAP 1
6 GET_ITER
>> 8 FOR_ITER 12 (to 22)
10 STORE_NAME 0 (i)
12 LOAD_NAME 1 (print)
14 LOAD_NAME 0 (i)
16 CALL_FUNCTION 1
18 POP_TOP
20 JUMP_ABSOLUTE 8
>> 22 LOAD_CONST 0 (None)
24 RETURN_VALUE
In [3]: dis.dis("for i in {None: None}.keys(): print(i)")
1 0 LOAD_CONST 0 (None)
2 LOAD_CONST 0 (None)
4 BUILD_MAP 1
6 LOAD_METHOD 0 (keys)
8 CALL_METHOD 0
10 GET_ITER
>> 12 FOR_ITER 12 (to 26)
14 STORE_NAME 1 (i)
16 LOAD_NAME 2 (print)
18 LOAD_NAME 1 (i)
20 CALL_FUNCTION 1
22 POP_TOP
24 JUMP_ABSOLUTE 12
>> 26 LOAD_CONST 0 (None)
28 RETURN_VALUE
Если вы хотите перебирать только ключи словаря, нет необходимости вызывать keys () - метод, который дает вам динамическое представление c для словаря записи.