В Python, что определяет порядок при переборе kwargs? - PullRequest
12 голосов
/ 23 января 2012

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

Ответы [ 6 ]

24 голосов
/ 23 января 2012

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

11 голосов
/ 23 января 2012

Это словарь.И, как упоминалось в документации, словарь не имеет порядка (из http://docs.python.org/tutorial/datastructures.html#dictionaries):

. Лучше всего думать о словаре как о неупорядоченном наборе key: valueпары , с требованием, чтобы ключи были уникальными (в пределах одного словаря).

Но вы можете сделать его обработанным в некотором порядке , например:

  • с использованием 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))))
    
6 голосов
/ 13 января 2017

Наконец, это было введено в 3.6 версии : dict теперь упорядочены, поэтому порядок аргументов ключевого слова сохраняется.

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 голосов
/ 24 января 2012

К сожалению, ирония в том, что диктовка ** kwargs означает, что следующее не будет работать (по крайней мере, не так, как можно было бы ожидать):

od = OrderedDict(a=1, b=2, c=3)

Поскольку ключевые аргументы вначале встроены в неупорядоченный диктант, вы не можете полагать, что они будут вставлены в OrderedDict в том порядке, в котором они перечислены. (

2 голосов
/ 23 января 2012

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

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

1 голос
/ 23 января 2012

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

...