Yanıtlar:
Eğer onun bir OrderedDict()
(anahtar, değer) çiftleri tuples aşağıdaki gibi elde ederek endeksleyerek öğeleri kolayca erişebilirsiniz
>>> 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')
Python 3.X için not
dict.items
bir liste yerine yinelenebilir bir dikte görüntüleme nesnesi döndürür . Endekslemeyi mümkün kılmak için çağrıyı bir listeye sarmamız gerekiyor
>>> items = list(d.items())
>>> items
[('foo', 'python'), ('bar', 'spam')]
>>> items[0]
('foo', 'python')
>>> items[1]
('bar', 'spam')
list(d.items())
list(d.items())
next(islice(d.items(), 1))
('bar', 'spam')
Bir OrderedDict kullanmak zorunda mısınız veya özellikle hızlı konum endeksleme ile bir şekilde sipariş edilen harita benzeri bir tip mi istiyorsunuz? İkincisi ise, Python'un sıralanmış birçok dikte türünü (anahtar sıralama düzenine göre anahtar / değer çiftleri sipariş eden) düşünün. Bazı uygulamalar hızlı indekslemeyi de destekler. Örneğin, sortcontainers projesi yalnızca bu amaç için bir SortedDict türüne sahiptir .
>>> 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
Karşılaştırmaları önlemek için bir tuş işleviyle de kullanabilirsiniz . Gibi: SortedDict(lambda key: 0, ...)
. Anahtarlar daha sonra ayrıştırılır, ancak kararlı bir sırada kalır ve dizine eklenebilir.
Bir liste oluşturmadan bir OrderedDict'ta ilk girişi (veya buna yakın) istiyorsanız özel bir durum burada . (Bu Python 3 olarak güncellendi):
>>> 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'
(İlk kez "next ()" demek, gerçekten "first" demek.)
Resmi olmayan next(iter(d.items()))
testimde, küçük bir OrderedDict ile sadece biraz daha hızlı items()[0]
. 10.000 girişlik OrderedDict ile next(iter(d.items()))
200 kat daha hızlıydı items()[0]
.
AMA öğeler () listesini bir kez kaydedip listeyi çok kullanırsanız, bu daha hızlı olabilir. Veya tekrar tekrar {bir öğe () yineleyicisi oluşturup istediğiniz konuma getirin}, bu daha yavaş olabilir.
OrderedDict
ler bir yok iteritems()
ilk öğeyi elde etmek için aşağıdakileri yapmanız gerekir, böylece yöntemi: next(iter(d.items()))
.
d.items()
bir yineleyici gibi görünmüyor, bu yüzden öndeki iter yardımcı olmayacak mı? Yine de listenin tamamını döndürecektir :(
odict_iterator
ve IRC #python'da listenin bir kopyasını oluşturmadığını doğruladı.
Kullanımı dramatik daha verimlidir IndexedOrderedDict gelen indexed
paketin.
Niklas'ın yorumundan sonra , OrderedDict ve IndexedOrderedDict üzerinde 1000 giriş ile bir kıyaslama yaptım .
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 , bu özel durumda belirli bir konumdaki öğeleri indekslemede ~ 100 kat daha hızlıdır.
indexed.py
Bunun yerine yüklemeyi deneyin indexed
.
Bu topluluk wiki mevcut yanıtları toplamaya çalışır.
Python 2.7
Piton 2'de, keys()
, values()
, ve items()
işlevleri OrderedDict
dönüş listeleri. values
Örnek olarak kullanmak , en basit yol
d.values()[0] # "python"
d.values()[1] # "spam"
Yalnızca tek bir endeks umurumda büyük koleksiyonları için, jeneratör sürümlerini kullanan tam listesi oluşturma önleyebilirsiniz, iterkeys
, itervalues
ve iteritems
:
import itertools
next(itertools.islice(d.itervalues(), 0, 1)) # "python"
next(itertools.islice(d.itervalues(), 1, 2)) # "spam"
İndexed.py paket sağlayan IndexedOrderedDict
bu kullanım şeklini tasarlanmıştır ve en hızlı seçenek olacak.
from indexed import IndexedOrderedDict
d = IndexedOrderedDict({'foo':'python','bar':'spam'})
d.values()[0] # "python"
d.values()[1] # "spam"
Rasgele erişimli büyük sözlükler için itervalues kullanmak oldukça hızlı olabilir:
$ 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 aynı iki temel seçeneğe sahiptir (list vs generator), ancak dikte yöntemleri varsayılan olarak jeneratörleri döndürür.
Liste yöntemi:
list(d.values())[0] # "python"
list(d.values())[1] # "spam"
Jeneratör yöntemi:
import itertools
next(itertools.islice(d.values(), 0, 1)) # "python"
next(itertools.islice(d.values(), 1, 2)) # "spam"
Python 3 sözlükleri, python 2'den daha hızlı bir büyüklük sırasına sahiptir ve jeneratörleri kullanmak için benzer hızlandırmalara sahiptir.
+--------+-----------+----------------+---------+
| size | list (ms) | generator (ms) | indexed |
+--------+-----------+----------------+---------+
| 1000 | .0316 | .0165 | .00262 |
| 10000 | .288 | .166 | .00294 |
| 100000 | 3.53 | 1.48 | .00332 |
+--------+-----------+----------------+---------+
Bu yeni bir dönem ve Python 3.6.1 ile sözlükler artık sıralarını koruyor. Bu anlambilim açık değildir, çünkü bu BDFL onayı gerektirir. Ama Raymond Hettinger bir sonraki en iyi şey (ve daha komik) ve oldukça güçlü bir dava yapıyor sözlüklerin çok uzun bir süre sipariş edileceği konusunda ortaya koyuyor.
Şimdi bir sözlük dilimi oluşturmak çok kolay:
test_dict = {
'first': 1,
'second': 2,
'third': 3,
'fourth': 4
}
list(test_dict.items())[:2]
Not: Dikte yerleştirme siparişi koruması artık Python 3.7'de resmidir .
OrderedDict () için, (anahtar, değer) çiftlerinin gruplarını aşağıdaki gibi alarak veya '.values ()' kullanarak dizin oluşturarak öğelere erişebilirsiniz.
>>> 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
yöntemin bir liste yerine bir bütünleşik sözlük görüntüleme nesnesi döndürdüğünü ve dilimleme veya dizine eklemeyi desteklemediğini unutmayın. Bu yüzden önce listeye dönüştürmeniz gerekir. docs.python.org/3.3/library/stdtypes.html#dict-views