একটি অজগর অভিধানে মানগুলি ম্যাপিং


243

আমি একটি ফাংশন পাস { k1: v1, k2: v2 ... }করতে চাই এমন একটি অভিধান দেওয়া হয়েছে যা পেতে চাই ।{ k1: f(v1), k2: f(v2) ... }f

ফাংশনে এমন কোনও বিল্ট রয়েছে? বা আমার কি করতে হবে

dict([(k, f(v)) for (k, v) in my_dictionary.iteritems()])

আদর্শভাবে আমি শুধু লিখতে হবে

my_dictionary.map_values(f)

অথবা

my_dictionary.mutate_values_with(f)

এটি হ'ল মূল অভিধানটি পরিবর্তন করা হয়েছে বা একটি অনুলিপি তৈরি করা আমার পক্ষে কিছু যায় আসে না।


2
আপনার উদাহরণ লেখার আরও ভাল উপায় হ'ল dict((k, f(v)) for k, v in mydict.iteritems())অর্থাত্ বর্গক্ষেত্র বন্ধনী ব্যতীত, এটি জেনারেটরের মাধ্যমে মধ্যবর্তী তালিকা তৈরির প্রতিরোধ করবে।
বেরিয়াল

উত্তর:


354

এ জাতীয় কোনও কার্য নেই; এটি করার সবচেয়ে সহজ উপায় হ'ল ডিক বোঝাপড়াটি ব্যবহার করা:

my_dictionary = {k: f(v) for k, v in my_dictionary.items()}

পাইথন ২.7-এ, স্মৃতি সংরক্ষণের .iteritems()পরিবর্তে পদ্ধতিটি ব্যবহার করুন .items()। অজগর ২.7 অবধি ডেক বোঝার বাক্য গঠন চালু হয়নি।

লক্ষ করুন যে তালিকায় এই জাতীয় কোনও পদ্ধতি নেই; আপনাকে একটি তালিকা বোধগম্যতা বা map()ফাংশনটি ব্যবহার করতে হবে।

এর ফলে, আপনি map()আপনার ডিকটি প্রক্রিয়া করার জন্যও এই ফাংশনটি ব্যবহার করতে পারেন :

my_dictionary = dict(map(lambda kv: (kv[0], f(kv[1])), my_dictionary.iteritems()))

তবে এটি আসলে পাঠযোগ্য নয়।


5
+1: এটি আমিও করতাম। dict(zip(a, map(f, a.values())))প্রান্তিকভাবে খাটো, তবে এটি কী করছে সে সম্পর্কে আমাকে ভাবতে হবে এবং নিজেকে স্মরণ করিয়ে দিতে হবে যে হ্যাঁ, কী এবং মানগুলি একই ক্রমে পুনরাবৃত্তি হয় যদি ডিকটি পরিবর্তন না হয়। ডিকটম্প কী করছে সে সম্পর্কে আমাকে কিছু ভাবতে হবে না এবং তাই এটি সঠিক উত্তর।
ডিএসএম

2
@ সিবির্গ: এটি একসাথে সমস্ত কী-মান জোড়গুলি অনুসন্ধান করার পরিবর্তে, আপনি এখন নম্বর-অফ-টাইম my_dictionary.__getitem__কলগুলি ব্যবহার করছেন।
মার্টিজন পিটারস

1
নোট করুন যেহেতু PEP3113 (পাইথন 3.x তে প্রয়োগ করা হয়েছে) টিউপল প্যারামিটারগুলি এখন আর সমর্থিত নয়: lambda (k,v): (k, f(v))lambda k_v: (k_v[0], f(k_v[1]))
এমনটি

1
প্যারামিটারটি আনপ্যাকিং কেন নিক্সড হল? কিভাবে এই উন্নতি হয় ?
জাভাদবা

3
এফপি ভাষা থেকে আগত পাইথনটিকে অবিশ্বাস্যরকম বিশ্রী মনে হবে।
juanchito


21

নতুন ডিক তৈরির পরিবর্তে আপনি এটি জায়গায় রাখতে পারেন, এটি বৃহত্তর অভিধানগুলির জন্য পছন্দনীয় হতে পারে (যদি আপনার অনুলিপিটির প্রয়োজন না হয়)।

def mutate_dict(f,d):
    for k, v in d.iteritems():
        d[k] = f(v)

my_dictionary = {'a':1, 'b':2}
mutate_dict(lambda x: x+1, my_dictionary)

my_dictionaryধারণ করে ফলাফল :

{'a': 2, 'b': 3}

1
শীতল, আপনার হয়ত নাম পরিবর্তন mapdictকরা উচিত mutate_values_withবা কিছু স্ফটিক পরিষ্কার করার জন্য আপনি ডেকে পুনরায় লেখেন! :)
তারশ্যাচ

2
zip(d.keys(), d.values())এর পরিবর্তে আরও সংস্করণগুলির জন্য কাজ করেiteritems()
ytpillai

1
@ytpillai 'জিপ' বা বোধগম্যতাগুলি অনুলিপি পরিবর্তে পরিবর্তে একটি অনুলিপি তৈরি করে, যা আমার উত্তরের উদ্দেশ্য। যখন কোনও অনুলিপি ঠিক আছে তার জন্য গৃহীত উত্তরটি সেরা।
জিনস

1
আমার ক্ষমা, আমি বুঝতে পারি নি আপনি আইটেম পদ্ধতিটি ব্যবহার করতে চেয়েছিলেন। তবে, এর সাথে আরও একটি উন্নতি সম্ভব (পাইথন ২.7 ব্যবহারকারীদের জন্য নয়){k:f(v) for k,v in iter(d.items())}
ytpillai

1
একটি পুনরুক্তি তৈরি করে স্থান বাঁচায়
ytpillai

13

দরুন PEP-0469 যা আইটেম iteritems () নতুন নামকরণ () এবং PEP-3113 যা মুছে unpacking প্যারামিটার Tuple , পাইথন মধ্যে 3.x আপনি লেখা উচিত Martijn Pieters ♦ উত্তর ভালো:

my_dictionary = dict(map(lambda item: (item[0], f(item[1])), my_dictionary.items()))

4

যদিও আমার আসল উত্তরটি বিন্দুটি মিস করেছে ( ডিফল্টর্টিক্টের কারখানায় অ্যাক্সেসিং কী সমাধানের সমাধান দিয়ে এই সমস্যাটি সমাধান করার চেষ্টা করে ), আমি বর্তমান প্রশ্নের প্রকৃত সমাধানের প্রস্তাব দেওয়ার জন্য এটি পুনরায় কাজ করেছি।

এটা এখানে:

class walkableDict(dict):
  def walk(self, callback):
    try:
      for key in self:
        self[key] = callback(self[key])
    except TypeError:
      return False
    return True

ব্যবহার:

>>> d = walkableDict({ k1: v1, k2: v2 ... })
>>> d.walk(f)

ধারণাটি হ'ল আসল ডিকটি এটিকে কাঙ্ক্ষিত কার্যকারিতা দেওয়ার জন্য সাবক্লাস করা: সমস্ত মানগুলির উপরে একটি ফাংশন "ম্যাপিং"।

প্লাস পয়েন্টটি হ'ল এই dictঅভিধানটি কলব্যাকের সাহায্যে অনুরোধে যে কোনও ডেটা রুপান্তর করার সময় মূল ডেটা সংরক্ষণ করার জন্য ব্যবহার করা যেতে পারে a

অবশ্যই, ক্লাস এবং ফাংশনটি আপনি যেভাবে চান তার নাম নির্দ্বিধায় বোধ করুন (এই উত্তরে নির্বাচিত নামটি পিএইচপি এর array_walk()ফাংশন দ্বারা অনুপ্রাণিত )।

দ্রষ্টব্য: কার্যকারিতার জন্য try- exceptব্লক বা returnবিবৃতি উভয়ই বাধ্যতামূলক নয়, তারা পিএইচপি-র আচরণের আরও নকল করার জন্য রয়েছে array_walk


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

কোন বিদ্যমান চাবি?
7heo.tk

ওপি থেকে: Given a dictionary { k1: v1, k2: v2 ... } ...। এটি হ'ল, আপনার ইতিমধ্যে dictশুরু করতে হবে ..
কাওস

আমি বলতে চাই যে আমরা দুজনেই ঠিক; তবে আমি বিশ্বাস করি যে আমরা দুজনেই ভুল। আপনি ঠিক বলেছেন যে আমার উত্তর প্রশ্নের উত্তর দেয় না; তবে আপনি যে কারণে অনুরোধ করেছিলেন তা নয়। আমি কেবল বিন্দু মিস দান প্রাপ্ত একটি উপায় {v1: f(v1), v2: f(v2), ...}দেওয়া [v1, v2, ...], এবং একটি অভি দেওয়া। আমি আমার উত্তরটি সংশোধন করব এটি সংশোধন করার জন্য।
7heo.tk

2

ল্যাম্বদার ভিতরে থেকে ইনডেক্সিং করা এড়াতে যেমন:

rval = dict(map(lambda kv : (kv[0], ' '.join(kv[1])), rval.iteritems()))

আপনি এটি করতে পারেন:

rval = dict(map(lambda(k,v) : (k, ' '.join(v)), rval.iteritems()))

এটি দ্বিতীয় উদাহরণে নিজেই 2-টিউপলের মধ্যে একটি চৌকস ম্যানিপুলেশন। তবে এটি ল্যাম্বডায় অটো টুপল আনপ্যাকিং ব্যবহার করে যা পাইথন ৩ এ আর সমর্থিত lambda(k,v)নয় Therefore সুতরাং কাজ করবে না। স্ট্যাকওভারফ্লো
জোনাথন কোমার

0

এই ব্যবহারের ক্ষেত্রে সবেমাত্র এসেছিল। আমি জিন্সের উত্তরটি বাস্তবায়িত করেছি , মানগুলি হ্যান্ডল করার জন্য একটি পুনরাবৃত্ত পদ্ধতির যোগ করে যা হ'ল:

def mutate_dict_in_place(f, d):
    for k, v in d.iteritems():
        if isinstance(v, dict):
            mutate_dict_in_place(f, v)
        else:
            d[k] = f(v)

# Exemple handy usage
def utf8_everywhere(d):
    mutate_dict_in_place((
        lambda value:
            value.decode('utf-8')
            if isinstance(value, bytes)
            else value
        ),
        d
    )

my_dict = {'a': b'byte1', 'b': {'c': b'byte2', 'd': b'byte3'}}
utf8_everywhere(my_dict)
print(my_dict)

পাইথন 2-এ বাইস হিসাবে স্ট্রিংগুলি এনকোড করে এমন json বা yaml ফাইলগুলির সাথে কাজ করার সময় এটি কার্যকর হতে পারে

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