2013-06-26 47 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] 

Khi tôi chạy chức năng shuffle, nó làm tăng lỗi sau, tại sao vậy?LoạiError: đối tượng 'dict_keys' không hỗ trợ lập chỉ mục

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

Câu hỏi của bạn là gì? X là gì? – Paco

+4

có vẻ như Bạn đang sử dụng python3 – oleg

+0

có vẻ là lỗi python3 – DataEngineer

Trả lời

113

Rõ ràng bạn đang chuyển qua d.keys() vào chức năng shuffle của bạn. Có lẽ điều này đã được viết bằng python2.x (khi d.keys() trả về một danh sách). Với python3.x, d.keys() trả về đối tượng dict_keys hoạt động giống như một số set hơn list. Như vậy, nó không thể được lập chỉ mục.

Giải pháp là để vượt qua list(d.keys()) (hoặc chỉ đơn giản là list(d)) đến shuffle.

+9

. . . Hoặc chỉ cần 'list (d)' sẽ cung cấp cho bạn một danh sách các khóa trên cả python2.x và python3.x mà không thực hiện bất kỳ bản sao nào :-) – mgilson

+5

Đây là một quyết định thiết kế thay đổi đột phá cho python3. – Jason

+4

Bạn có thể nghĩ như vậy, nhưng tôi chắc chắn nghĩ rằng đó là quyết định đúng đắn. Đối tượng 'dict_keys' hoạt động nhiều hơn giống như chỉ một nửa số phím của một dict. Cụ thể, họ hỗ trợ kiểm tra thành viên O (1) (và các phương thức giống như thiết lập khác có thể được triển khai hiệu quả trên thực tế đó). Những điều này là không thể với một danh sách và nếu bạn muốn một danh sách các phím của dict, bạn đã luôn luôn có thể chỉ đơn giản là làm 'danh sách (your_dictionary)' để có được nó. – mgilson

8

Bạn đang chuyển kết quả của somedict.keys() đến hàm. Trong Python 3, dict.keys không trả về một danh sách, nhưng một đối tượng được thiết lập đại diện cho chế độ xem các phím của từ điển và (được đặt giống) không hỗ trợ lập chỉ mục.

Để khắc phục sự cố, hãy sử dụng list(somedict.keys()) để thu thập khóa và làm việc với điều đó.

1

Tại sao bạn cần triển khai ngẫu nhiên khi nó đã tồn tại? Ở trên vai của những người khổng lồ.

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

Câu trả lời là kiến ​​thức chung có liên quan, nhưng nó không đề cập đến những gì OP yêu cầu. –

+0

Bạn nói đúng. Có vẻ như anh ta muốn thực hiện ngẫu nhiên của riêng mình. –

+0

psah, có lẽ anh ta không thực sự biết rằng anh ta có thể sử dụng built-in, nhưng câu hỏi thực sự có vẻ là về một loại lỗi. Tuy nhiên, tôi hy vọng anh ta đã chuyển đổi và sử dụng tùy chọn của bạn (trừ khi nó là một cái gì đó rất cụ thể) để tuân theo các nguyên tắc cơ bản về DRY và kinh tế mã. –

0

chuyển đổi lặp đi lặp lại vào danh sách có thể có chi phí thay vì nó, bạn có thể sử dụng

next(iter(keys)) 

cho mặt hàng đầu tiên hoặc nếu bạn muốn itrate tất cả các mục sử dụng

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

Trong Python 2 dict .keys() trả về một danh sách, trong khi trong Python 3 nó trả về một trình tạo.

Bạn chỉ có thể lặp lại các giá trị của nó khác mà bạn có thể phải chuyển đổi nó một cách rõ ràng thành danh sách, tức là chuyển nó vào một hàm danh sách.

+0

Chỉ muốn nói rằng kiểu trả về là của kiểu máy phát. Hy vọng nó sẽ giúp OP! – DeWil

Các vấn đề liên quan