সংগ্রহগুলিতে আইটেমগুলি অ্যাক্সেস করা হচ্ছে index


142

বলি আমার কাছে নিম্নলিখিত কোড রয়েছে:

import collections
d = collections.OrderedDict()
d['foo'] = 'python'
d['bar'] = 'spam'

সংখ্যাযুক্ত পদ্ধতিতে আমি আইটেমগুলি অ্যাক্সেস করতে পারি এমন কোনও উপায় আছে, যেমন:

d(0) #foo's Output
d(1) #bar's Output

উত্তর:


181

যদি এটির হয় তবে OrderedDict()আপনি নিম্নরূপে (কী, মান) জোড়ার টিপলগুলি পেয়ে সূচকের মাধ্যমে উপাদানগুলিতে সহজেই অ্যাক্সেস করতে পারেন

>>> 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')

পাইথন ৩. এক্স এর জন্য নোট

dict.itemsতালিকার পরিবর্তে পুনরাবৃত্তিযোগ্য ডেক ভিউ অবজেক্টটি ফিরিয়ে আনবে । আমাদের সূচীকরণটি সম্ভব করার জন্য আমাদের একটি তালিকাতে কলটি মোড়ানো দরকার

>>> items = list(d.items())
>>> items
[('foo', 'python'), ('bar', 'spam')]
>>> items[0]
('foo', 'python')
>>> items[1]
('bar', 'spam')

21
নোট করুন যে itemsx.x এ পদ্ধতিটি তালিকার পরিবর্তে একটি নির্ভরযোগ্য অভিধানের ভিউ অবজেক্টটি প্রদান করে এবং স্লাইসিং বা ইনডেক্সিং সমর্থন করে না। সুতরাং আপনাকে প্রথমে এটি একটি তালিকায় পরিণত করতে হবে। docs.python.org/3.3/library/stdtyype.html#dict-views
পিটার

8
তালিকায় আইটেম, মান বা কীগুলি অনুলিপি করা বড় স্বৈরশাসকদের জন্য বেশ ধীর হতে পারে। অ্যাপ্লিকেশনগুলির জন্য একটি খুব অভ্যন্তরীণ ডেটাস্ট্রাকচারের সাথে আমি অর্ডারডিক্ট () এর একটি পুনর্লিখন তৈরি করেছি যেগুলি প্রায়শই এটি করতে হয়: github.com/niklasf/indexed.py
নিক্লাস

1
@ পিটারডিগ্লপারকে আমি কীভাবে এটি একটি তালিকাতে পরিণত করব?
দেজেল

1
@ ডিজেল - কনস্ট্রাক্টরটি ব্যবহার করুন:list(d.items())
পিটার ডিগ্রোপার

8
আপনি শুধুমাত্র এক্সেস একটি আইটেম থাকে, তাহলে আপনি এর ওভারহেড মেমরির এড়াতে পারেন list(d.items())ব্যবহার করে next(islice(d.items(), 1))পেতে('bar', 'spam')
Quantum7

24

আপনার কি অর্ডারডিক্ট ব্যবহার করতে হবে বা আপনি বিশেষত কোনও মানচিত্রের মতো ধরণ চান যা দ্রুত পজিশনাল সূচী দিয়ে কোনওভাবে অর্ডার করা হয়? যদি পরবর্তীটি হয়, তবে পাইথনের অনেকগুলি সাজানো ডিকের ধরণের (যা কী বাছাই ক্রমের উপর ভিত্তি করে কী-মান জোড়গুলির অর্ডার দেয়) বিবেচনা করুন। কিছু বাস্তবায়ন দ্রুত সূচককে সমর্থন করে। উদাহরণস্বরূপ, সোর্টার্ড কনটেনার প্রজেক্টের কেবল এই উদ্দেশ্যে একটি সাজানো ডিক্ট টাইপ রয়েছে।

>>> 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'

1
SortedDictতুলনা এড়াতে আপনি একটি মূল ফাংশন দিয়েও ব্যবহার করতে পারেন । ভালো লেগেছে: SortedDict(lambda key: 0, ...)। কীগুলি তারপরে অকার্যকর হয়ে যাবে তবে স্থিতিশীল ক্রমে থাকবে এবং তা ইনডেক্সযোগ্য।
গ্রান্টজে

19

আপনি যদি তালিকা তৈরি না করেই অর্ডারডিক্টে প্রথম প্রবেশ (বা এটির কাছাকাছি) চান তবে এখানে একটি বিশেষ কেস দেওয়া আছে । (এটি পাইথন 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'

(আপনি প্রথমবার "পরের ()" বলছেন, এর সত্যিকার অর্থে "প্রথম"।)

আমার অনানুষ্ঠানিক পরীক্ষায়, next(iter(d.items()))একটি ছোট্ট অর্ডারডিক্টের চেয়ে সামান্য কিছুটা দ্রুত items()[0]। ১০,০০০ এন্ট্রি নিয়ে অর্ডারডিক্ট সহ next(iter(d.items()))প্রায় ২০০ গুণ বেশি দ্রুত ছিল items()[0]

কিন্তু যদি আপনি আইটেম () সংরক্ষণ তালিকা একবার এবং তারপর তালিকার অনেক ব্যবহার, দ্রুত হতে পারে। অথবা আপনি যদি বারবার {কোনও আইটেম () পুনরুক্তি তৈরি করেন এবং এটির মাধ্যমে আপনি যে অবস্থানে চলে যান step, এটি ধীর হতে পারে।


10
পাইথন 3 OrderedDicts এর একটি হবে না iteritems()যাতে আপনি অর্ডার প্রথম আইটেম প্রাপ্ত নিম্নোক্ত কাজ করতে হবে, পদ্ধতি: next(iter(d.items()))
নাথান ওসমান

পাইথন 3 তে d.items()কোনও পুনরুক্তিমান বলে মনে হচ্ছে না, সুতরাং সামনে এটির সাহায্য করবে না? এটি এখনও সম্পূর্ণ তালিকাটি ফেরত
পাঠাবে

1
আপডেট: আমি ভুল ছিলাম, ইটার (d.items ()) ফিরে আসে odict_iteratorএবং আইআরসি # প্যাকেটে আমাকে নিশ্চিত করা হয়েছিল যে এটি তালিকার অনুলিপি তৈরি করে না।
জিজ্ঞাসা করুন

@ নাথান ওসমান, নুড করার জন্য ধন্যবাদ। আমি শেষ পর্যন্ত পাইথন 3 এ নিজেকে আপডেট করেছি!
স্টিভ উইথাম ডুপ্লিকেট

14

প্যাকেজ থেকে সূচিপত্রকৃত ডিক্ট ব্যবহার করা নাটকীয়ভাবে আরও দক্ষ indexed

নিক্লাসের মন্তব্যের পরে, আমি অর্ডারডটিক্ট এবং ইনডেক্সডঅর্ডারডিক্টে 1000 টি এন্ট্রি সহ একটি মানদণ্ড করেছি ।

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

ইনডেক্সডঅর্ডারডিক্ট এই নির্দিষ্ট ক্ষেত্রে সুনির্দিষ্ট অবস্থানে থাকা উপাদানগুলিকে ইনডেক্স করার ক্ষেত্রে 100 গুণ গতিযুক্ত


নিস! দুর্ভাগ্যক্রমে আনাকান্দায় এখনও নেই।
কনস্টান্টিন

1
@ কনস্ট্যান্টিন প্যাকেজের আসল নামটি indexed.py । এর indexed.pyপরিবর্তে ইনস্টল করার চেষ্টা করুন indexed
সোভেন হেইল

9

এই সম্প্রদায়ের উইকি বিদ্যমান উত্তরগুলি সংগ্রহ করার চেষ্টা করে।

পাইথন 2.7

পাইথন 2, ইন keys(), values()এবং items()কার্যাবলী OrderedDictআগমন তালিকা। valuesউদাহরণ হিসাবে ব্যবহার করে , সবচেয়ে সহজ উপায়

d.values()[0]  # "python"
d.values()[1]  # "spam"

বড় সংগ্রহের জন্য যেখানে আপনি কেবলমাত্র একটি একক সূচক সম্পর্কে যত্নশীল, আপনি জেনারেটর সংস্করণ ব্যবহার করে এবং পুরো তালিকা তৈরি করা এড়াতে পারেন iterkeys, itervaluesএবং iteritems:

import itertools
next(itertools.islice(d.itervalues(), 0, 1))  # "python"
next(itertools.islice(d.itervalues(), 1, 2))  # "spam"

Indexed.py প্যাকেজ উপলব্ধ IndexedOrderedDict, যা এই ব্যবহারের ক্ষেত্রে জন্য ডিজাইন করা হয়েছে এবং দ্রুততম বিকল্প হতে হবে।

from indexed import IndexedOrderedDict
d = IndexedOrderedDict({'foo':'python','bar':'spam'})
d.values()[0]  # "python"
d.values()[1]  # "spam"

এ্যাটারভ্যালুগুলি ব্যবহার করা এলোমেলো অ্যাক্সেস সহ বৃহত্তর অভিধানের জন্য যথেষ্ট দ্রুত হতে পারে:

$ 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  |
+--------+-----------+----------------+---------+

পাইথন ৩.6

পাইথন 3 তে একই দুটি বেসিক বিকল্প রয়েছে (তালিকা বনাম জেনারেটর), তবে ডিক পদ্ধতিগুলি জেনারেটরগুলি ডিফল্টরূপে ফিরিয়ে দেয়।

তালিকা পদ্ধতি:

list(d.values())[0]  # "python"
list(d.values())[1]  # "spam"

জেনারেটর পদ্ধতি:

import itertools
next(itertools.islice(d.values(), 0, 1))  # "python"
next(itertools.islice(d.values(), 1, 2))  # "spam"

পাইথন 3 অভিধান অজগর 2 এর চেয়ে দ্রুত গতির একটি ক্রম এবং জেনারেটর ব্যবহারের জন্য একই ধরণের স্পিডআপ রয়েছে।

+--------+-----------+----------------+---------+
|  size  | list (ms) | generator (ms) | indexed |
+--------+-----------+----------------+---------+
|   1000 | .0316     | .0165          | .00262  |
|  10000 | .288      | .166           | .00294  |
| 100000 | 3.53      | 1.48           | .00332  |
+--------+-----------+----------------+---------+

7

এটি একটি নতুন যুগ এবং পাইথনের ৩.6.১ অভিধানের সাহায্যে এখন তাদের ক্রম বজায় রয়েছে। এই শব্দার্থকগুলি স্পষ্ট নয় কারণ এর জন্য বিডিএফএল অনুমোদনের প্রয়োজন হবে। তবে রেমন্ড হেটেঞ্জার হলেন পরবর্তী সেরা জিনিস (এবং মজাদার) এবং তিনি একটি সুন্দর দৃ case় মামলা করেছেন যে অভিধানগুলি খুব দীর্ঘ সময়ের জন্য অর্ডার করা হবে।

সুতরাং এখন অভিধানের টুকরোগুলি তৈরি করা সহজ:

test_dict = {
                'first':  1,
                'second': 2,
                'third':  3,
                'fourth': 4
            }

list(test_dict.items())[:2]

দ্রষ্টব্য: ডিক্টোনারি সন্নিবেশ-অর্ডার সংরক্ষণ এখন পাইথন ৩.7 এ অফিসিয়াল


0

অর্ডারডিক্ট () এর জন্য আপনি (কী, মান) জোড়ার টিপলগুলি নিম্নরূপে বা '.ভ্যালু ()' ব্যবহার করে সূচিক্যকরণের মাধ্যমে উপাদানগুলিতে অ্যাক্সেস করতে পারেন

>>> 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']
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.