В 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 в свою функцию?

+12
источник поделиться
6 ответов

kwargs - словарь. Словари неупорядочены - просто поставлены, порядок не определен и деталь реализации. Подглядывание под капотом покажет, что порядок сильно варьируется в зависимости от хеш-значений элементов, порядка вставки и т.д., Поэтому вам лучше не полагаться на что-либо, связанное с ним.

+24
источник

Это словарь. И, как упоминалось в документации, словарь не имеет порядка (из 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))))
    
+10
источник

Несчастная ирония заключается в том, что определение ** 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'])
+3
источник

Так как kwargs - это словарь Python, который реализуется как хеш-таблица, его упорядочение не сохраняется и является фактически случайным.

На самом деле, как исправление недавней проблемы безопасности на многих языках программирования, в будущем порядок может даже измениться между вызовами вашей программы (вызовы интерпретатора Python).

+2
источник

kwargs - словарь, на Python они не упорядочены, поэтому результат по существу (псевдо) случайный.

+1
источник

Посмотрите другие вопросы по меткам или Задайте вопрос