পাইথনে অভিধান অনুলিপি করার দ্রুত উপায়


92

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

কীগুলি স্ট্রিং, মানগুলি পূর্ণসংখ্যা (0/1)।

আমি বর্তমানে একটি সহজ উপায় ব্যবহার করছি:

newDict = oldDict.copy()

আমার কোডটি প্রোফাইলিং করা দেখায় যে অনুলিপি অপারেশন বেশিরভাগ সময় নেয়।

dict.copy()পদ্ধতির আরও দ্রুত বিকল্প আছে ? দ্রুততম কি হবে?


4
মান যদি 0 বা 1 হয়, তবে boolএটির চেয়ে ভাল পছন্দ কি হতে পারে int?
সমীর তালওয়ার

4
এবং যদি আপনার হাজার হাজার অনুলিপিগুলির প্রয়োজন হয়, তবে বিটমাস্কগুলি আরও ভাল কাজ করবে?
Wooble

@ সমীর যেভাবেই boolপাইথনের নাম নেই int
সান্তা

যদিও আমি একমত, যে বিটমাস্ক আপনার জন্য আরও দক্ষ হতে পারে (আপনি কীভাবে এই "ডিক" ব্যবহার করেন তার উপর নির্ভর করে)।
সান্তা

4
পরিষ্কার করার জন্য, boolটাইপটি আসলে টাইপের একটি সাবক্লাস (সাব intটাইপ ?) ।
সান্তা

উত্তর:


64

এ খুঁজছি সি উৎস পাইথন জন্য dictঅপারেশন, আপনি দেখতে পারেন যে তারা একটি প্রশংসনীয় সাদাসিধা (কিন্তু দক্ষ) কপি না। এটি মূলত এই কলটিতে সিদ্ধ হয় PyDict_Merge:

PyDict_Merge(PyObject *a, PyObject *b, int override)

এটি যদি একই জিনিস হয় এবং যদি তাদের মধ্যে কোনও বস্তু পেয়ে থাকে তবে এই জিনিসগুলির জন্য দ্রুত চেক করে। এর পরে এটি লক্ষ্য ডিকের জন্য উদার এক-সময় পুনরায় আকার / বরাদ্দ করে এবং তারপরে উপাদানগুলি একে একে অনুলিপি করে। বিল্ট-ইন-এর চেয়ে বেশি দ্রুত আপনাকে দেখতে পাচ্ছি না copy()


4
ডিক্টের ব্যবহার এড়াতে আমি কোডটি আরও ভালভাবে পুনরায় লেখার মতো শোনায় - বা একই কাজ করতে পারে এমন একটি দ্রুত ডেটা কাঠামো ব্যবহার করি। উত্তরের জন্য আপনাকে অনেক ধন্যবাদ!
জোর্ন

56

আপনি যেমন বলছেন ততই দৃশ্যত ডিক্ট কপি দ্রুততর।

[utdmr@utdmr-arch ~]$ python -m timeit -s "d={1:1, 2:2, 3:3}" "new = d.copy()"
1000000 loops, best of 3: 0.238 usec per loop
[utdmr@utdmr-arch ~]$ python -m timeit -s "d={1:1, 2:2, 3:3}" "new = dict(d)"
1000000 loops, best of 3: 0.621 usec per loop
[utdmr@utdmr-arch ~]$ python -m timeit -s "from copy import copy; d={1:1, 2:2, 3:3}" "new = copy(d)"
1000000 loops, best of 3: 1.58 usec per loop

তুলনার জন্য ধন্যবাদ! বেশিরভাগ জায়গায় ডিক কপির ব্যবহার এড়াতে কোডটি পুনরায় লেখার চেষ্টা করবে। আবার ধন্যবাদ!
জোর্ন

4
পথ আমদানি প্রত্যেক সময় সাথে আছেন করছেন খরচ বেড়ে চলেছে ছাড়া গত তুলনা করতে timeitএর -sযুক্তি: python -m timeit -s "from copy import copy" "new = copy({1:1, 2:2, 3:3})"। আপনি যখন এটির সময়ে, ডিক সৃষ্টিটিও টানুন (সমস্ত উদাহরণের জন্য)
টমাস ওয়াউটারস

একটি নির্দিষ্ট শটের কিছু ওঠানামা থাকতে পারে বলে অনেক সময় প্রক্রিয়াগুলি পুনরাবৃত্তি করা ভাল।
xiaohan2012

4
টাইমিট তা করে; যেমন এটি বলে যে এটি 1000000 বার লুপ করে এবং এটি গড়।
utdemir

আমার বিবাদমান সময় রয়েছে। a = {b: b এর জন্য পরিসীমা (10000)} ইন [5]:% টাইমিট কপি (ক) 10000 লুপ, প্রতি লুপে 3: 186 µ এস সেরা: [6]:% টাইমাইট ডিপকপি (ক) 100 লুপ, লুপ প্রতি 3: 14.1 এমএসের মধ্যে সেরা: [7]:% টাইমিট এএকপি () 1000 লুপ, প্রতি লুপে 3: 180
দাউদ তাগাওহী-নেজাদ

12

আপনি কি একটি কোড নমুনা সরবরাহ করতে পারেন যাতে আমি দেখতে পাচ্ছি আপনি কীভাবে অনুলিপি ব্যবহার করছেন () এবং কোন প্রসঙ্গে?

আপনি ব্যবহার করতে পারেন

new = dict(old)

তবে আমি মনে করি না এটি আরও দ্রুত হবে।


5

আমি বুঝতে পারি এটি একটি পুরানো থ্রেড, তবে এটি "ডিক কপি পাইথন" এর অনুসন্ধান ইঞ্জিনগুলির একটি উচ্চ ফলাফল এবং "ডিক কপি পারফরম্যান্স" এর শীর্ষ ফলাফল এবং আমি বিশ্বাস করি এটি প্রাসঙ্গিক।

পাইথন ৩.7 থেকে, newDict = oldDict.copy()এটি আগের তুলনায় 5.5x পর্যন্ত দ্রুত। উল্লেখযোগ্যভাবে, এই মুহুর্তে, newDict = dict(oldDict)এই পারফরম্যান্সটি বৃদ্ধি পেয়েছে বলে মনে হয় না।

এখানে আরও কিছু তথ্য রয়েছে


3

আপনি জল্পনা থেকে যে জিনিসগুলি রেখে গেছেন তার উপর নির্ভর করে আপনি মূল অভিধানটি মোড়ানো এবং এক ধরণের করতে চাইতে পারেন অনুলিপিতে কপি ।

"অনুলিপি" হ'ল একটি অভিধান যা "প্যারেন্ট" অভিধানে স্টাফ দেখায়, যদি এতে ইতিমধ্যে কী থাকে না --- তবে নিজেই স্টাফ পরিবর্তন করে।

এটি ধরে নিয়েছে যে আপনি মূলটি সংশোধন করবেন না এবং অতিরিক্ত অনুসন্ধানগুলি আরও বেশি ব্যয় করে না।


2

পরিমাপ যদিও অভিধানের আকারের উপর নির্ভর করে। 10000 এন্ট্রিগুলির জন্য অনুলিপি (ডি) এবং ডি কোডপি () প্রায় একই রকম।

a = {b: b for b in range(10000)} 
In [5]: %timeit copy(a)
10000 loops, best of 3: 186 µs per loop
In [6]: %timeit deepcopy(a)
100 loops, best of 3: 14.1 ms per loop
In [7]: %timeit a.copy()
1000 loops, best of 3: 180 µs per loop
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.