পাইথন অভিধান: কীগুলির তালিকার জন্য মানগুলির তালিকা পান


179

সংশ্লিষ্ট আইটেমগুলির তালিকা পেতে অভিধানের কীগুলির একটি তালিকা ব্যবহার করার জন্য কি অন্তর্নির্মিত / দ্রুত উপায় আছে?

উদাহরণস্বরূপ আমার আছে:

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

আমি কীভাবে mykeysঅভিধানের সাথে সম্পর্কিত মানগুলি তালিকা হিসাবে ব্যবহার করতে পারি ?

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

উত্তর:


205

একটি তালিকা বোধগম্যতা এটি করার একটি ভাল উপায় বলে মনে হচ্ছে:

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

1
যদি mydictকোনও ফাংশন কল হয় (যা ডিক্ট ফেরায়) তবে এটি ফাংশনটিকে একাধিকবার কল করে, তাই না?
এন্ডোলিথ

1
@ এন্ডোলিথ হ্যাঁ এটি হবে
এরিক রোমরেল

107

তালিকা-সংকলন ব্যতীত অন্য কয়েকটি উপায়:

  • কী না পাওয়া গেলে তালিকা তৈরি করুন এবং ব্যতিক্রম নিক্ষেপ করুন: 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

দ্রষ্টব্য : পাইথন 3-এ, 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)

পাইথন ৩.6.৪ এর জন্য আপডেট করুন:

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'পাইথন ২.7 এ দেয় ; `পাওয়া_কিজ = [ম্যাপিং-তে কীগুলির কী (যদি পুনরাবৃত্তিতে কী ব্যবহার করা হয়]] ভাল কাজ করে
নটগেইল


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]

@ পিটারডিগ্লপারকে আপনি বিভ্রান্ত করছেন items()পছন্দসই, এটি অতিরিক্ত অনুসন্ধান করতে হবে না, len(mydict)*len(mykeys)এখানে কোনও অপারেশন নেই! (লক্ষ্য করুন যে আমি একটি সেট ব্যবহার করছি)
আস্কর লোপেজ

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

@ ইন্সপেক্টর জি ৪ ডিজেট @ পিটারডিজপ্লপার সদস্যতার ক্রিয়াকলাপ mykeysনিয়মিতভাবে নিয়মিতভাবে চালিত হয়েছে , আমি একটি সেট ব্যবহার করছি না, একটি তালিকা নয়
Óscar López ২

2
কমপক্ষে ওপি-র তালিকাটি কোনও সেটে রূপান্তরিত করা এটিকে রৈখিক করে তোলে তবে এটি এখনও ভুল ডেটা কাঠামোর পাশাপাশি লাইন অর্ডার হারানোর ক্ষেত্রেও রৈখিক। মেকিগুলিতে একটি 10 ​​কে অভিধান এবং 2 কীগুলির ক্ষেত্রে বিবেচনা করুন। আপনার সমাধানটি সাধারণ তালিকা বোধগম্যের জন্য দুটি অভিধানের অনুসন্ধানের তুলনায় 10 কে সেট সদস্যতার পরীক্ষা করে। সাধারণভাবে এটি ধরে নেওয়া নিরাপদ বলে মনে হচ্ছে যে কীগুলির সংখ্যা অভিধানের উপাদানের সংখ্যার চেয়ে কম হবে - এবং যদি এটি না হয় তবে আপনার পদ্ধতির পুনরাবৃত্তি উপাদানগুলিকে বাদ দেওয়া হবে।
পিটার DeGlopper


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
বিল্ট ইন পদ্ধতিগুলি কার্যকর তবে তারা প্রদত্ত কীগুলির তালিকা থেকে সংশ্লিষ্ট আইটেমগুলির একটি তালিকা দেয় না list এই উত্তরটি এই বিশেষ প্রশ্নের সঠিক উত্তর নয়।
স্টেনিক্স

-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,[])

যদি সেখানে কী না থাকে তবে ডিকের মধ্যে নেই।

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