2012-01-23 26 views
12

在Python中,我寫了這個功能來教自己如何**kwargs作品的Python:在Python中,什麼決定了通過kwargs迭代時的順序?

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循環之前的A2即使我喂A2到我的功能首先打印的A3的價值?

回答

24

kwargs是一本字典。字典是無序的 - 簡單地說,訂單是未指定的和實現細節。在引擎蓋下窺視將顯示訂單的變化很大程度上取決於項目的哈希值,插入順序等,因此您最好不要依賴與其相關的任何事情。

1

kwargs是一本字典,在Python這些不排序,這樣的結果基本上是(僞)隨機的。

10

這是一本詞典。而且,如在文檔中提到的,字典裏沒有爲了(從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)))) 
    
+0

見我的答案是關於OrderedDict – PaulMcG

+0

@PaulMcGuire:。見我的評論給你的答案 – Tadeck

+0

難道你不會寫爲'fxn(3,** OrderedDict(etc ...'?哦,等等,我看到你改變了簽名來取代字典,而不是一組關鍵字參數。如果你要改變簽名,那麼你可能只是傳遞你的鍵值元組列表,但是OP真的想迭代** kwargs。 – PaulMcG

2

由於kwargs是一個Python 字典,這是爲hash table實現的,其順序是不保留,實際上是隨機的。

實際上,作爲近期在許多編程語言中使用的security issue的修補程序,將來在您的程序調用(Python解釋器的調用)之間甚至可能會改變順序。

+2

不是隨機的 - 事實上,它是完全確定的。只是不容易預測,因爲它取決於散列。 –

+1

你當然是對的。這就是我說「有效隨機」的原因,向讀者表明他不應該試圖猜測它。在附註中,幾乎計算機所做的每件事都是確定性的,但可能不容易預測:) – spatz

4

不幸諷刺意味的是** kwargs的字典-ification意味着以下將無法正常工作(至少不是人們所期望的方式):

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

由於keyworded ARG遊戲首先建成一個無序的字典,你不能依靠他們將按照他們列出的順序插入OrderedDict。:(

+1

但是,以下內容將會:'od = OrderedDict((('a',1),('b',2),(' C」,3)))'。所以基本上'** kwargs',因爲它是一個'dict',不會有任何順序,但是你總是可以傳遞'OrderedDict'作爲參數,並且它會有你想要的順序。 – Tadeck

3

這終於在3.6 release介紹現在的**kwargsOrderedDict,因此關鍵字參數順序被保存

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']) 
+0

在Python 3.6中'** kwargs'不是'OrderedDict'。他們仍然是一個'字典',但現在'字典'是有序的。 –