В Python, что определяет порядок при итерации через kwargs?
В python я написал эту функцию, чтобы научить себя, как **kwargs
работает в Python:
def fxn(a1, **kwargs):
print a1
for k in kwargs:
print k, " : ", kwargs[k]
Затем я вызывал эту функцию с
fxn(3, a2=2, a3=3, a4=4)
Вот результат, который напечатал мой интерпретатор Python:
3
a3 : 3
a2 : 2
a4 : 4
Почему цикл for печатал значение a3 до того, как он был равен a2, даже если я сначала подал a2 в свою функцию?
Ответы
Ответ 1
kwargs
- словарь. Словари неупорядочены - просто поставлены, порядок не определен и деталь реализации. Подглядывание под капотом покажет, что порядок сильно варьируется в зависимости от хеш-значений элементов, порядка вставки и т.д., Поэтому вам лучше не полагаться на что-либо, связанное с ним.
Ответ 2
Это словарь. И, как упоминалось в документации, словарь не имеет порядка (из http://docs.python.org/tutorial/datastructures.html#dictionaries):
Лучше всего подумать о словаре как о неупорядоченном наборе пар ключ: значение, с требованием, чтобы ключи были уникальными (в пределах одного словаря).
Но вы можете сделать его обработанным в некотором порядке, например:
-
с помощью sorted()
:
def fxn(a1, **kwargs):
print a1
for k in sorted(kwargs): # notice "kwargs" replaced by "sorted(kwargs)"
print k, " : ", kwargs[k]
-
или используя тип OrderedDict
(вы можете передать объект OrderedDict
как параметр, содержащий все пары значений ключа):
from collections import OrderedDict
def fxn(a1, ordkwargs):
print a1
for k in ordkwargs:
print k, " : ", ordkwargs[k]
fxn(3, OrderedDict((('a2',2), ('a3',3), ('a4',4))))
Ответ 3
Несчастная ирония заключается в том, что определение ** kwargs означает, что следующее не будет работать (по крайней мере, не так, как можно было бы ожидать):
od = OrderedDict(a=1, b=2, c=3)
Так как аргументы с ключевыми словами сначала встроены в неупорядоченный dict, вы не можете зависеть от того, что они будут вставлены в OrderedDict в том порядке, в котором они перечислены.: (
Ответ 4
Это наконец было введено в 3.6 release. **kwargs
теперь OrderedDict
, поэтому порядок аргументов ключевого слова сохраняется.
Python 3.6.0 (default, Jan 13 2017, 13:27:48)
>>> def print_args(**kwargs):
... print(kwargs.keys())
...
>>> print_args(first=1, second=2, third=3)
dict_keys(['first', 'second', 'third'])
Ответ 5
Так как kwargs
- это словарь Python, который реализуется как хеш-таблица, его упорядочение не сохраняется и является фактически случайным.
На самом деле, как исправление недавней проблемы безопасности на многих языках программирования, в будущем порядок может даже измениться между вызовами вашей программы (вызовы интерпретатора Python).
Ответ 6
kwargs
- словарь, на Python они не упорядочены, поэтому результат по существу (псевдо) случайный.