Как распаковать словарь для того, чтобы он был пропущен? - PullRequest
0 голосов
/ 01 июня 2018

Это следующая проблема:

main_module.py

from collections import OrderedDict
from my_other_module import foo

a = OrderedDict([
    ('a', 1),
    ('b', 2),
    ('c', 3),
    ('d', 4),
    ])

foo(**a)

my_other_module.py

def foo(**kwargs):
    for k, v in kwargs.items():
        print k, v

Когда я запускаю main_module.py Я ожидаю получить распечатку в указанном порядке:

a 1
b 2
c 3
d 4

Но вместо этого я получаю:

a 1
c 3
b 2
d 4

Я понимаю, что этоимеет какое-то отношение к тому, как реализован оператор ** и каким-то образом он теряет порядок передачи словарных пар. Также я понимаю, что словари в python не упорядочены как списки, потому что они реализованы в виде хеш-таблиц.Могу ли я применить какой-нибудь «хак», чтобы получить поведение, необходимое в этом контексте?

PS - В моей ситуации я не могу отсортировать словарь внутри функции foo, так как нет правилза которым можно следовать, кроме строгого порядка, в котором передаются значения.

1 Ответ

0 голосов
/ 01 июня 2018

Используя **a, вы распаковываете упорядоченный словарь в словарь аргументов.

Так что, когда вы вводите в foo, kwargs просто словарь,с гарантированным порядком (если вы не используете Python 3.6+, но это все еще деталь реализации в 3.6, но порядок становится официальным в 3.7: Упорядочены ли словари в Python 3.6 +? )

В этом случае вы можете просто потерять упаковку / распаковку, чтобы она была переносимой для более старых версий python.

from collections import OrderedDict

def foo(kwargs):
    for k, v in kwargs.items():
        print(k, v)

a = OrderedDict([
    ('a', 1),
    ('b', 2),
    ('c', 3),
    ('d', 4),
    ])

foo(a)
...