2013-08-31 64 views
50

Tôi đang cố gắng để truy cập vào các yếu tố của một dict_key bởi chỉ số của nó:Truy cập yếu tố dict_keys bởi chỉ mục trong Python3

test = {'foo': 'bar', 'hello': 'world'} 
keys = test.keys() # dict_keys object 

keys.index(0) 
AttributeError: 'dict_keys' object has no attribute 'index' 

Tôi muốn nhận foo.

cùng với:

keys[0] 
TypeError: 'dict_keys' object does not support indexing 

Làm thế nào tôi có thể làm điều này?

+6

Trong py3.x 'dict.keys()' trả về một tập hợp như đối tượng xem, không phải danh sách (vì vậy, không thể lập chỉ mục). Sử dụng 'keys = list (test)' –

+0

khi tôi làm danh sách (something_dict), thứ tự tuple là ngẫu nhiên: ví dụ: list ({'foo': 'bar', 'hello': 'world'}) có thể trả về : danh sách (foo, hello) hoặc danh sách (hello, foo), tại sao điều này là ngẫu nhiên? – fj123x

+1

[Dicts không có bất kỳ thứ tự nào] (http://stackoverflow.com/questions/526125/why-is-python-ordering-my-dictionary-like-so). (Sử dụng 'collections.OrderedDict' nếu bạn muốn các phím được đặt hàng) –

Trả lời

64

Gọi list() trên từ điển thay vì:

keys = list(test) 

Trong Python 3, phương pháp dict.keys() trả về một dictionary view object, hoạt động như một bộ. Lặp lại từ điển trực tiếp cũng tạo ra khóa, vì vậy hãy chuyển từ điển sang danh sách kết quả trong danh sách tất cả các phím:

>>> test = {'foo': 'bar', 'hello': 'world'} 
>>> list(test) 
['foo', 'hello'] 
>>> list(test)[0] 
'foo' 
+2

[ Xem ra cho danh sách (dict.keys()) trong Python 3 - Labix Blog] (http://blog.labix.org/2008/06/27/watch-out-for-listdictkeys-in-python-3) rõ ràng giải thích vấn đề là gì mà không cung cấp giải pháp. Thật tuyệt vời! –

+0

@BrandonBradley: nói chung: dựa vào hành động nhất định là nguyên tử là một ý tưởng tồi anyway, như Python là rất cao năng động. Mã của bạn có thể dễ dàng được chuyển qua một lớp con 'dict', ví dụ, trong đó' .keys() 'được xử lý trong mã Python (ví dụ: một chuyển đổi luồng có thể xảy ra). –

25

Không phải là câu trả lời đầy đủ nhưng có thể là gợi ý hữu ích. Nếu nó thực sự là mục đầu tiên bạn muốn *, sau đó

next(iter(q)) 

là nhanh hơn nhiều so

list(q)[0] 

cho dicts lớn, vì toàn bộ điều không nhất thiết phải được lưu trữ trong bộ nhớ.

Đối với 10.000.000 mục tôi thấy nó nhanh hơn gần 40.000 lần.

* Mục đầu tiên trong trường hợp lệnh dict chỉ là một mục giả ngẫu nhiên trước Python 3.6 (sau khi nó được đặt hàng trong quá trình triển khai chuẩn, mặc dù không nên dựa vào nó).

+0

Điều này luôn là một trong những vấn đề lớn nhất của tôi với mọi thứ trở thành trình lặp trong Py3. Nó chắc chắn hiệu quả hơn, nhưng rất nhiều trường hợp sử dụng trở nên "ô uế" và phức tạp không có lý do. Ví dụ, tại sao họ không thể chỉ hỗ trợ lập chỉ mục trên trình lặp, mà không nhất thiết phải mất một hiệu suất? –