पायथन शब्दकोश: कुंजियों की सूची के लिए मूल्यों की सूची प्राप्त करें


182

क्या संबंधित वस्तुओं की सूची पाने के लिए शब्दकोश की चाबियों की सूची का उपयोग करने का एक अंतर्निहित / त्वरित तरीका है?

उदाहरण के लिए मेरे पास:

>>> mydict = {'one': 1, 'two': 2, 'three': 3}
>>> mykeys = ['three', 'one']

मैं mykeysएक सूची के रूप में शब्दकोश में संबंधित मूल्यों को प्राप्त करने के लिए कैसे उपयोग कर सकता हूं ?

>>> mydict.WHAT_GOES_HERE(mykeys)
[3, 1]

जवाबों:


206

ऐसा करने के लिए एक सूची समझदारी एक अच्छा तरीका है:

>>> [mydict[x] for x in mykeys]
[3, 1]

1
यदि mydictकोई फ़ंक्शन कॉल है (जो एक तानाशाह को लौटाता है) तो यह फ़ंक्शन को कई बार कॉल करता है, है ना?
3

1
@endolith हां यह होगा
एरिक रोमेलेल

108

सूची-COMP के अलावा अन्य तरीकों की एक जोड़ी:

  • यदि नहीं मिला तो सूची बनाएं और अपवाद छोड़ें: map(mydict.__getitem__, mykeys)
  • Noneकुंजी नहीं मिली तो सूची बनाएं :map(mydict.get, mykeys)

वैकल्पिक रूप से, operator.itemgetterटपल का उपयोग करके वापस किया जा सकता है:

from operator import itemgetter
myvalues = itemgetter(*mykeys)(mydict)
# use `list(...)` if list is required

नोट : Python3 में, mapसूची के बजाय एक पुनरावृत्तिकर्ता को लौटाता है। list(map(...))एक सूची के लिए उपयोग करें ।


54

थोड़ा गति तुलना:

Python 2.7.11 |Anaconda 2.4.1 (64-bit)| (default, Dec  7 2015, 14:10:42) [MSC v.1500 64 bit (AMD64)] on win32
In[1]: l = [0,1,2,3,2,3,1,2,0]
In[2]: m = {0:10, 1:11, 2:12, 3:13}
In[3]: %timeit [m[_] for _ in l]  # list comprehension
1000000 loops, best of 3: 762 ns per loop
In[4]: %timeit map(lambda _: m[_], l)  # using 'map'
1000000 loops, best of 3: 1.66 µs per loop
In[5]: %timeit list(m[_] for _ in l)  # a generator expression passed to a list constructor.
1000000 loops, best of 3: 1.65 µs per loop
In[6]: %timeit map(m.__getitem__, l)
The slowest run took 4.01 times longer than the fastest. This could mean that an intermediate result is being cached 
1000000 loops, best of 3: 853 ns per loop
In[7]: %timeit map(m.get, l)
1000000 loops, best of 3: 908 ns per loop
In[33]: from operator import itemgetter
In[34]: %timeit list(itemgetter(*l)(m))
The slowest run took 9.26 times longer than the fastest. This could mean that an intermediate result is being cached 
1000000 loops, best of 3: 739 ns per loop

इसलिए लिस्ट कॉम्प्रिहेंशन और आइटमगेटर ऐसा करने के सबसे तेज़ तरीके हैं।

अद्यतन: बड़ी यादृच्छिक सूचियों और मानचित्रों के लिए मेरे पास कुछ अलग परिणाम थे:

Python 2.7.11 |Anaconda 2.4.1 (64-bit)| (default, Dec  7 2015, 14:10:42) [MSC v.1500 64 bit (AMD64)] on win32
In[2]: import numpy.random as nprnd
l = nprnd.randint(1000, size=10000)
m = dict([(_, nprnd.rand()) for _ in range(1000)])
from operator import itemgetter
import operator
f = operator.itemgetter(*l)
%timeit f(m)
%timeit list(itemgetter(*l)(m))
%timeit [m[_] for _ in l]  # list comprehension
%timeit map(m.__getitem__, l)
%timeit list(m[_] for _ in l)  # a generator expression passed to a list constructor.
%timeit map(m.get, l)
%timeit map(lambda _: m[_], l)
1000 loops, best of 3: 1.14 ms per loop
1000 loops, best of 3: 1.68 ms per loop
100 loops, best of 3: 2 ms per loop
100 loops, best of 3: 2.05 ms per loop
100 loops, best of 3: 2.19 ms per loop
100 loops, best of 3: 2.53 ms per loop
100 loops, best of 3: 2.9 ms per loop

तो इस मामले में स्पष्ट विजेता है f = operator.itemgetter(*l); f(m), और स्पष्ट बाहरी व्यक्ति map(lambda _: m[_], l):।

अजगर के लिए अद्यतन 3.6.4:

import numpy.random as nprnd
l = nprnd.randint(1000, size=10000)
m = dict([(_, nprnd.rand()) for _ in range(1000)])
from operator import itemgetter
import operator
f = operator.itemgetter(*l)
%timeit f(m)
%timeit list(itemgetter(*l)(m))
%timeit [m[_] for _ in l]  # list comprehension
%timeit list(map(m.__getitem__, l))
%timeit list(m[_] for _ in l)  # a generator expression passed to a list constructor.
%timeit list(map(m.get, l))
%timeit list(map(lambda _: m[_], l)
1.66 ms ± 74.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
2.1 ms ± 93.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
2.58 ms ± 88.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
2.36 ms ± 60.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
2.98 ms ± 142 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
2.7 ms ± 284 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
3.14 ms ± 62.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

तो, पायथन 3.6.4 के परिणाम लगभग समान हैं।


15

यहाँ तीन तरीके हैं।

KeyErrorकुंजी नहीं मिलने पर उठाना :

result = [mapping[k] for k in iterable]

लापता कुंजी के लिए डिफ़ॉल्ट मान।

result = [mapping.get(k, default_value) for k in iterable]

गायब कुंजी।

result = [mapping[k] for k in iterable if k in mapping]

found_keys = mapping.keys() & iterableTypeError: unsupported operand type(s) for &: 'list' and 'list'अजगर 2.7 पर देता है ; `Found_keys = [मैपिंग में कुंजी के लिए कुंजी ।keys () अगर iterable में कुंजी] सबसे अच्छा काम करता है
NotGaeL


7

इसे इस्तेमाल करे:

mydict = {'one': 1, 'two': 2, 'three': 3}
mykeys = ['three', 'one'] # if there are many keys, use a set

[mydict[k] for k in mykeys]
=> [3, 1]

@PeterDeGlopper आप भ्रमित हैं। items()पसंद किया जाता है, इसे अतिरिक्त देखने की ज़रूरत नहीं है, len(mydict)*len(mykeys)यहाँ कोई ऑपरेशन नहीं है! (ध्यान दें कि मैं एक सेट का उपयोग कर रहा हूं)
óscar López

@ You'rescarLópez हां, आप शब्दकोश के हर तत्व का निरीक्षण कर रहे हैं। iteritems उन्हें तब तक उपज नहीं देता है जब तक आपको उनकी आवश्यकता नहीं होती है, इसलिए यह एक मध्यस्थ सूची बनाने से बचता है, लेकिन आप अभी भी 'mykeys' में ऑर्डर करते हैं (ऑर्डर लेन (mykeys), क्योंकि यह mydict में प्रत्येक k के लिए एक सूची है)। पूरी तरह से अनावश्यक रूप से, सरल सूची की तुलना में यह समझ में आता है कि सिर्फ mykeys पर चलता है।
पीटर ड्यूगॉपर

@ inspectorG4dget @PeterDeGlop पर सदस्यता अभियान को mykeysलगातार समय पर परिचालित किया जाता है, मैं सेट का उपयोग कर रहा हूं, सूची नहीं
dscar López

2
ओपी की सूची को एक सेट में परिवर्तित करना कम से कम इसे रैखिक बनाता है, लेकिन यह अभी भी गलत डेटा संरचना के साथ-साथ ऑर्डर खोने के कारण भी रैखिक है। Myk में 10k शब्दकोश और 2 कुंजी के मामले पर विचार करें। आपका समाधान सरल सूची समझ के लिए दो शब्दकोश देखने की तुलना में 10k सेट सदस्यता परीक्षण करता है। सामान्य तौर पर यह मान लेना सुरक्षित है कि कुंजी की संख्या शब्दकोश तत्वों की संख्या से छोटी होगी - और यदि यह नहीं है, तो आपका दृष्टिकोण दोहराया तत्वों को छोड़ देगा।
पीटर डीग्लॉपर


1

पंडों ने इसे बहुत शान से किया, हालाँकि टो लिस्ट की समझ हमेशा अधिक तकनीकी रूप से पाइथोनिक होगी। मेरे पास अभी गति तुलना में लगाने का समय नहीं है (मैं बाद में वापस आऊंगा और इसमें डालूँगा):

import pandas as pd
mydict = {'one': 1, 'two': 2, 'three': 3}
mykeys = ['three', 'one']
temp_df = pd.DataFrame().append(mydict)
# You can export DataFrames to a number of formats, using a list here. 
temp_df[mykeys].values[0]
# Returns: array([ 3.,  1.])

# If you want a dict then use this instead:
# temp_df[mykeys].to_dict(orient='records')[0]
# Returns: {'one': 1.0, 'three': 3.0}

-1

या सिर्फ mydict.keys()शब्दकोश के लिए एक अंतर्निहित विधि कॉल है। इसके अलावा का पता लगाने mydict.values()और mydict.items()

// आह, ओपी पोस्ट ने मुझे भ्रमित कर दिया।


5
बिल्ट इन मेथड्स उपयोगी हैं, लेकिन वे दिए गए कीज़ की सूची से संबंधित वस्तुओं की सूची नहीं देते हैं। यह उत्तर इस विशेष प्रश्न का सही उत्तर नहीं है।
स्टेनिक्स

-1

पायथन को बंद करने के बाद : एक दिए गए आदेश के साथ तानाशाही मूल्यों से एक सूची बनाने का कुशल तरीका

सूची बनाए बिना कुंजियों को पुनः प्राप्त करना:

from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import collections


class DictListProxy(collections.Sequence):
    def __init__(self, klist, kdict, *args, **kwargs):
        super(DictListProxy, self).__init__(*args, **kwargs)
        self.klist = klist
        self.kdict = kdict

    def __len__(self):
        return len(self.klist)

    def __getitem__(self, key):
        return self.kdict[self.klist[key]]


myDict = {'age': 'value1', 'size': 'value2', 'weigth': 'value3'}
order_list = ['age', 'weigth', 'size']

dlp = DictListProxy(order_list, myDict)

print(','.join(dlp))
print()
print(dlp[1])

उत्पादन:

value1,value3,value2

value3

जो सूची द्वारा दिए गए आदेश से मेल खाता है


-2
reduce(lambda x,y: mydict.get(y) and x.append(mydict[y]) or x, mykeys,[])

incase वहाँ चाबियाँ तानाशाही में नहीं हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.