Câu trả lời:
Nếu đó là một OrderedDict()
bạn có thể dễ dàng truy cập các phần tử bằng cách lập chỉ mục bằng cách lấy các bộ dữ liệu của các cặp (khóa, giá trị) như sau
>>> import collections
>>> d = collections.OrderedDict()
>>> d['foo'] = 'python'
>>> d['bar'] = 'spam'
>>> d.items()
[('foo', 'python'), ('bar', 'spam')]
>>> d.items()[0]
('foo', 'python')
>>> d.items()[1]
('bar', 'spam')
Lưu ý cho Python 3.X
dict.items
sẽ trả về một đối tượng xem chính tả lặp đi lặp lại thay vì một danh sách. Chúng tôi cần phải kết thúc cuộc gọi vào một danh sách để có thể lập chỉ mục
>>> items = list(d.items())
>>> items
[('foo', 'python'), ('bar', 'spam')]
>>> items[0]
('foo', 'python')
>>> items[1]
('bar', 'spam')
list(d.items())
list(d.items())
bằng cách sử dụng next(islice(d.items(), 1))
để nhận('bar', 'spam')
Bạn có phải sử dụng OrderedDict hay bạn đặc biệt muốn một loại giống như bản đồ được sắp xếp theo cách nào đó với lập chỉ mục vị trí nhanh? Nếu sau này, hãy xem xét một trong nhiều loại chính tả được sắp xếp của Python (sắp xếp các cặp giá trị khóa dựa trên thứ tự sắp xếp khóa). Một số triển khai cũng hỗ trợ lập chỉ mục nhanh. Ví dụ, dự án sortcontainers có loại SortedDict cho mục đích này.
>>> from sortedcontainers import SortedDict
>>> sd = SortedDict()
>>> sd['foo'] = 'python'
>>> sd['bar'] = 'spam'
>>> print sd.iloc[0] # Note that 'bar' comes before 'foo' in sort order.
'bar'
>>> # If you want the value, then simple do a key lookup:
>>> print sd[sd.iloc[1]]
'python'
SortedDict
với một chức năng chính để tránh so sánh. Giống như : SortedDict(lambda key: 0, ...)
. Các khóa sau đó sẽ không được sắp xếp nhưng sẽ vẫn ở trạng thái ổn định và có thể lập chỉ mục.
Đây là trường hợp đặc biệt nếu bạn muốn mục đầu tiên (hoặc gần với nó) trong OrderedDict, mà không tạo danh sách. (Điều này đã được cập nhật lên Python 3):
>>> from collections import OrderedDict
>>>
>>> d = OrderedDict()
>>> d["foo"] = "one"
>>> d["bar"] = "two"
>>> d["baz"] = "three"
>>> next(iter(d.items()))
('foo', 'one')
>>> next(iter(d.values()))
'one'
(Lần đầu tiên bạn nói "next ()", nó thực sự có nghĩa là "lần đầu tiên.")
Trong thử nghiệm không chính thức của tôi, next(iter(d.items()))
với một OrderedDict nhỏ chỉ nhanh hơn một chút items()[0]
. Với OrderedDict gồm 10.000 mục, next(iter(d.items()))
nhanh hơn khoảng 200 lần items()[0]
.
NHƯNG nếu bạn lưu danh sách các mặt hàng () một lần và sau đó sử dụng danh sách rất nhiều, điều đó có thể nhanh hơn. Hoặc nếu bạn lặp đi lặp lại {tạo một trình vòng lặp vật phẩm () và bước qua nó đến vị trí bạn muốn}, điều đó có thể chậm hơn.
OrderedDict
không có một iteritems()
phương thức, vì vậy bạn sẽ cần phải làm như sau để có được mục đầu tiên : next(iter(d.items()))
.
d.items()
dường như không phải là một trình vòng lặp, vậy iter ở phía trước sẽ không giúp ích gì? Nó vẫn sẽ trả về danh sách đầy đủ :(
odict_iterator
và được xác nhận với tôi trên IRC #python rằng điều này không tạo ra một bản sao của danh sách.
Nó hiệu quả hơn đáng kể khi sử dụng IndexedOrderedDict từ indexed
gói.
Theo nhận xét của Niklas, tôi đã thực hiện một điểm chuẩn trên OrderedDict và IndexedOrderedDict với 1000 mục.
In [1]: from numpy import *
In [2]: from indexed import IndexedOrderedDict
In [3]: id=IndexedOrderedDict(zip(arange(1000),random.random(1000)))
In [4]: timeit id.keys()[56]
1000000 loops, best of 3: 969 ns per loop
In [8]: from collections import OrderedDict
In [9]: od=OrderedDict(zip(arange(1000),random.random(1000)))
In [10]: timeit od.keys()[56]
10000 loops, best of 3: 104 µs per loop
IndexedOrderedDict nhanh hơn ~ 100 lần trong các phần tử lập chỉ mục ở vị trí cụ thể trong trường hợp cụ thể này.
indexed.py
thay vì indexed
.
Wiki cộng đồng này cố gắng thu thập các câu trả lời hiện có.
Python 2.7
Trong python 2, keys()
, values()
, và items()
chức năng của OrderedDict
danh sách trở lại. Sử dụng values
làm ví dụ, cách đơn giản nhất là
d.values()[0] # "python"
d.values()[1] # "spam"
Đối với các bộ sưu tập rộng lớn, nơi bạn chỉ quan tâm đến một chỉ số duy nhất, bạn có thể tránh tạo ra danh sách đầy đủ bằng cách sử dụng các phiên bản máy phát điện, iterkeys
, itervalues
và iteritems
:
import itertools
next(itertools.islice(d.itervalues(), 0, 1)) # "python"
next(itertools.islice(d.itervalues(), 1, 2)) # "spam"
Các indexed.py gói cung cấp IndexedOrderedDict
, được thiết kế đối với trường hợp sử dụng này và sẽ là lựa chọn nhanh nhất.
from indexed import IndexedOrderedDict
d = IndexedOrderedDict({'foo':'python','bar':'spam'})
d.values()[0] # "python"
d.values()[1] # "spam"
Sử dụng itervalues có thể nhanh hơn đáng kể cho các từ điển lớn với quyền truy cập ngẫu nhiên:
$ python2 -m timeit -s 'from collections import OrderedDict; from random import randint; size = 1000; d = OrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); d.values()[i:i+1]'
1000 loops, best of 3: 259 usec per loop
$ python2 -m timeit -s 'from collections import OrderedDict; from random import randint; size = 10000; d = OrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); d.values()[i:i+1]'
100 loops, best of 3: 2.3 msec per loop
$ python2 -m timeit -s 'from collections import OrderedDict; from random import randint; size = 100000; d = OrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); d.values()[i:i+1]'
10 loops, best of 3: 24.5 msec per loop
$ python2 -m timeit -s 'from collections import OrderedDict; from random import randint; size = 1000; d = OrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); next(itertools.islice(d.itervalues(), i, i+1))'
10000 loops, best of 3: 118 usec per loop
$ python2 -m timeit -s 'from collections import OrderedDict; from random import randint; size = 10000; d = OrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); next(itertools.islice(d.itervalues(), i, i+1))'
1000 loops, best of 3: 1.26 msec per loop
$ python2 -m timeit -s 'from collections import OrderedDict; from random import randint; size = 100000; d = OrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); next(itertools.islice(d.itervalues(), i, i+1))'
100 loops, best of 3: 10.9 msec per loop
$ python2 -m timeit -s 'from indexed import IndexedOrderedDict; from random import randint; size = 1000; d = IndexedOrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); d.values()[i]'
100000 loops, best of 3: 2.19 usec per loop
$ python2 -m timeit -s 'from indexed import IndexedOrderedDict; from random import randint; size = 10000; d = IndexedOrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); d.values()[i]'
100000 loops, best of 3: 2.24 usec per loop
$ python2 -m timeit -s 'from indexed import IndexedOrderedDict; from random import randint; size = 100000; d = IndexedOrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); d.values()[i]'
100000 loops, best of 3: 2.61 usec per loop
+--------+-----------+----------------+---------+
| size | list (ms) | generator (ms) | indexed |
+--------+-----------+----------------+---------+
| 1000 | .259 | .118 | .00219 |
| 10000 | 2.3 | 1.26 | .00224 |
| 100000 | 24.5 | 10.9 | .00261 |
+--------+-----------+----------------+---------+
Python 3.6
Python 3 có hai tùy chọn cơ bản giống nhau (danh sách so với trình tạo), nhưng các phương thức dict trả về các trình tạo theo mặc định.
Danh sách phương pháp:
list(d.values())[0] # "python"
list(d.values())[1] # "spam"
Phương pháp máy phát điện:
import itertools
next(itertools.islice(d.values(), 0, 1)) # "python"
next(itertools.islice(d.values(), 1, 2)) # "spam"
Từ điển Python 3 là một thứ tự có độ lớn nhanh hơn python 2 và có tốc độ tương tự để sử dụng máy phát điện.
+--------+-----------+----------------+---------+
| size | list (ms) | generator (ms) | indexed |
+--------+-----------+----------------+---------+
| 1000 | .0316 | .0165 | .00262 |
| 10000 | .288 | .166 | .00294 |
| 100000 | 3.53 | 1.48 | .00332 |
+--------+-----------+----------------+---------+
Đó là một kỷ nguyên mới và với từ điển Python 3.6.1 hiện vẫn giữ trật tự của chúng. Những ngữ nghĩa này không rõ ràng bởi vì điều đó sẽ yêu cầu phê duyệt BDFL. Nhưng Raymond Hettinger là điều tốt nhất tiếp theo (và hài hước hơn) và anh ấy làm một vụ án khá mạnh mẽ rằng từ điển sẽ được đặt hàng trong một thời gian rất dài.
Vì vậy, bây giờ thật dễ dàng để tạo các lát của một từ điển:
test_dict = {
'first': 1,
'second': 2,
'third': 3,
'fourth': 4
}
list(test_dict.items())[:2]
Lưu ý: Bảo quản thứ tự chèn Dictonary hiện là chính thức trong Python 3.7 .
đối với OrderedDict () bạn có thể truy cập các phần tử bằng cách lập chỉ mục bằng cách lấy các bộ dữ liệu của các cặp (khóa, giá trị) như sau hoặc sử dụng '.values ()'
>>> import collections
>>> d = collections.OrderedDict()
>>> d['foo'] = 'python'
>>> d['bar'] = 'spam'
>>> d.items()
[('foo', 'python'), ('bar', 'spam')]
>>>d.values()
odict_values(['python','spam'])
>>>list(d.values())
['python','spam']
items
phương thức trả về một đối tượng xem từ điển có thể thay thế thay vì một danh sách và không hỗ trợ cắt hoặc lập chỉ mục. Vì vậy, bạn phải biến nó thành một danh sách đầu tiên. docs.python.org/3.3/l Library / stdtypes.html