2013-06-26 67 views
67
def shuffle(self, x, random=None, int=int): 
    """x, random=random.random -> shuffle list x in place; return None. 

    Optional arg random is a 0-argument function returning a random 
    float in [0.0, 1.0); by default, the standard random.random. 
    """ 

    randbelow = self._randbelow 
    for i in reversed(range(1, len(x))): 
     # pick an element in x[:i+1] with which to exchange x[i] 
     j = randbelow(i+1) if random is None else int(random() * (i+1)) 
     x[i], x[j] = x[j], x[i] 

當我運行shuffle函數時,會引發以下錯誤,爲什麼會這樣?TypeError:'dict_keys'對象不支持索引

TypeError: 'dict_keys' object does not support indexing 
+0

你的問題是什麼?什麼是x? – Paco

+4

它看起來像你正在使用python3 – oleg

+0

似乎是一個python3錯誤 – DataEngineer

回答

113

顯然你正在傳遞d.keys()shuffle功能。可能這是用python2.x編寫的(當d.keys()返回一個列表)。使用python3.x,d.keys()返回一個dict_keys對象,其行爲比list更像set。因此,它不能被索引。

解決方案是通過list(d.keys())(或簡單地list(d))到shuffle

+9

。 。 。或者只是'list(d)',它會給你一個python2.x和python3.x上的密鑰列表,而不需要做任何複製:-) – mgilson

+5

這是一個奇怪的改變python3的設計決策。 – Jason

+4

你可能會這樣想,但我絕對認爲這是正確的決定。 'dict_keys'對象的行爲更像是一個字典的一半。具體而言,它們支持O(1)成員資格測試(以及其他類似方法,可以在此基礎上有效實施)。這些東西對於列表來說是不可能的,如果你想要一個dict的鍵列表,你總是可以簡單地執行'list(your_dictionary)'來獲得它。 – mgilson

8

您將somedict.keys()的結果傳遞給函數。在Python 3中,dict.keys不返回列表,但代表字典鍵和視圖(類似於set)的類集對象不支持索引。

要解決此問題,請使用list(somedict.keys())收集密鑰並使用該密鑰。

1

爲什麼當它已經存在時需要實施洗牌?留在巨人的肩膀上。

import random 

d1 = {0:'zero', 1:'one', 2:'two', 3:'three', 4:'four', 
    5:'five', 6:'six', 7:'seven', 8:'eight', 9:'nine'} 

keys = list(d1) 
random.shuffle(keys) 

d2 = {} 
for key in keys: d2[key] = d1[key] 

print(d1) 
print(d2) 
+0

答案是一般知識相關的,但它沒有解決OP要求的內容。 –

+0

你說得對。他似乎想要實現他自己的隨機數發生器。 –

+0

psah,也許他實際上並不知道他可以使用內置的,但問題實際上似乎是關於類型錯誤。儘管如此,我希望他切換並使用你的選擇(除非它是非常具體的),以遵循基本的DRY和代碼經濟原則。 –

0

轉換迭代到列表可能會遇到成本,而不是它,你可以使用

next(iter(keys)) 

的第一個項目,或者如果你想itrate所有項目使用

items = iter(keys) 
while True: 
    try: 
     item = next(items) 
    except StopIteration as e: 
     pass # finish 
1

在Python 2字典.keys()返回一個列表,而在Python 3中返回一個生成器。

你只能迭代它的值,否則你可能不得不將它明確地轉換爲列表,即將它傳遞給列表函數。

+0

只是想說,返回類型是發生器的類型。希望它有助於OP! – DeWil