পাইথন: এন তালিকার একটি তালিকা তৈরির দ্রুততম উপায়


98

সুতরাং আমি ভাবছিলাম যে কীভাবে ফাঁকা তালিকার একটি তালিকা তৈরি করা যায়:

[[],[],[]...]

পাইথন কীভাবে মেমরির তালিকাগুলির সাথে কাজ করে, এটি কাজ করে না:

[[]]*n

এটি তৈরি করে [[],[],...]তবে প্রতিটি উপাদান একই তালিকা:

d = [[]]*n
d[0].append(1)
#[[1],[1],...]

একটি তালিকা বোঝার মতো কিছু কাজ করে:

d = [[] for x in xrange(0,n)]

তবে এটি লুপিংয়ের জন্য পাইথন ভিএম ব্যবহার করে। অন্তর্নিহিত লুপটি ব্যবহার করার কোনও উপায় আছে (এর সুবিধা সিটিতে লেখা হচ্ছে)?

d = []
map(lambda n: d.append([]),xrange(0,10))

এটি আসলে ধীর। :(


4
এর চেয়ে যথেষ্ট গতিযুক্ত কিছু থাকলে আমি অবাক হব d = [[] for x in xrange(0,n)]। আপনাকে হয় পাইথনে স্পষ্টভাবে লুপ করতে হবে বা বার বার পাইথন ফাংশন / ল্যাম্বদা কল করতে হবে (যা ধীরে ধীরে হওয়া উচিত)। তবে এখনও আশা করি কেউ এমন কিছু পোস্ট করবেন যা দেখায় যে আমি ভুল :)
এম এ কে

4
আপনি যখন এগুলি মাপলেন তখন আপনি timeitকী শিখলেন?
এস.লট

আমি কেবল নিশ্চিত করেছি যে map(lambda x: [], xrange(n))এটি তালিকা বোধের চেয়ে ধীর।
অ্যান্ড্রু ক্লার্ক

উত্তর:


105

সম্ভবত একমাত্র উপায় যা তুলনায় সামান্য দ্রুত

d = [[] for x in xrange(n)]

হয়

from itertools import repeat
d = [[] for i in repeat(None, n)]

এটি intপ্রতিটি পুনরাবৃত্তিতে একটি নতুন অবজেক্ট তৈরি করতে হবে না এবং আমার মেশিনে প্রায় 15% দ্রুত।

সম্পাদনা করুন : নুমপি ব্যবহার করে আপনি পাইথন লুপটি এড়াতে পারবেন

d = numpy.empty((n, 0)).tolist()

তবে এটি তালিকার বোধগমের চেয়ে 2.5 গুণ ধীর।


কীভাবে map(lambda x:[], repeat(None,n))?
PaulMcG

4
@ পল: ল্যাম্বডা এক্সপ্রেশনটির ফাংশন কল ওভারহেডের কারণে এটি আবার ধীর হবে।
সোভেন মারনাচ

পাইথন 3-তে এই পরিসীমাটি এখন আলাদা হওয়া উচিত?
beruic

@ বেরুয়িক আমি প্রথম কোড ব্লকের প্রশ্ন থেকে কোডটি উদ্ধৃত করছি, সুতরাং এটি পরিবর্তন করা সত্যিকার অর্থে তা বোঝায় না।
সোভেন মারনাচ

12

তালিকা comprehensions আসলে স্পষ্ট looping (দেখুন তুলনায় আরো দক্ষতার সঙ্গে প্রয়োগ করা হয় উদাহরণস্বরূপ কাজকর্মের জন্য আউটপুট ) এবং পথ প্রতি পুনরাবৃত্তির, যা যথেষ্ট ওভারহেড ওভারহেড incurs উপর একটি ophaque callable বস্তুর ডাকা হয়েছে।dismap

নির্বিশেষে, [[] for _dummy in xrange(n)]এটি করার সঠিক উপায় এবং ক্ষুদ্রের কোনওটিই নয় (যদি তা বিদ্যমান থাকে) অন্যান্য বিভিন্ন উপায়ে গতির পার্থক্য বিবেচনা করা উচিত। অবশ্যই আপনি নিজের বেশিরভাগ সময় এটি করতে ব্যয় করেন না - তবে সেই ক্ষেত্রে আপনার পরিবর্তে আপনার অ্যালগরিদমে কাজ করা উচিত। আপনি কতবার এই তালিকা তৈরি করেন?


4
_ভেরিয়েবল নাম হিসাবে দয়া করে না ! অন্যথায় চমৎকার উত্তর :)
সোভেন মারনাচ

11
@ সেভেন: কেন নয়? এটি সাধারণত অব্যবহৃত ভেরিয়েবলের জন্য ব্যবহৃত হয় (যদি এটি ডাকা হত i, আমি এটির জন্য কোথায় এটি ব্যবহার করব তা খুঁজছিলাম)। একমাত্র সমস্যাটি _হ'ল এটি আরইপিএলের শেষ ফলাফলটি ছায়া দেয় ... এবং এটি কেবল ২.x এর ক্ষেত্রে যেখানে তালিকা বোধগম্যতা ফাঁস হয়।

খুব প্রায়শই হয় না, এজন্যই আমি এগিয়ে গিয়ে একটি তালিকা বোধগম্যতা ব্যবহার করি। ভেবেছি লোকেরা কী বলবে তা দেখতে আকর্ষণীয় হবে। আমি পাইকনে ড্রপবক্সে আলিঙ্গনটি দেখেছি এমডি 5 হ্যাশকে একটি অযৌক্তিকভাবে প্রচুর পরিমাণে আপডেট করার জন্য লুপের পরিবর্তে আইটারটোলস.আইম্যাপ ব্যবহার করে এবং তখন থেকেই আমি সি লুপগুলিতে কিছুটা আবেশ পেয়েছি।
munchybunch

12
এটি ব্যবহার না করার সর্বাধিক গুরুত্বপূর্ণ কারণটি হ'ল এটি মানুষকে বিভ্রান্ত করে, তাদের মনে করে যে এটি কোনও ধরণের বিশেষ বাক্য গঠন। এবং _ইন্টারেক্টিভ দোভাষীর সাথে দ্বন্দ্বের পাশাপাশি এটি সাধারণ গেটেক্সটেক্স ওরফেও বিরোধ করে। যদি আপনি স্পষ্ট করতে চান যে ভেরিয়েবলটি একটি ডামি ভেরিয়েবল, তবে এটি কল করুন dummy, না _
সোভেন মারনাচ

12

এখানে দুটি পদ্ধতি রয়েছে, একটি মিষ্টি এবং সহজ (এবং ধারণাগত), অন্যটি আরও আনুষ্ঠানিক এবং একটি ডেটাसेट পড়ার পরে বিভিন্ন পরিস্থিতিতে বাড়ানো যেতে পারে।

পদ্ধতি 1: ধারণাগত

X2=[]
X1=[1,2,3]
X2.append(X1)
X3=[4,5,6]
X2.append(X3)
X2 thus has [[1,2,3],[4,5,6]] ie a list of lists. 

পদ্ধতি 2: আনুষ্ঠানিক এবং এক্সটেনসিবল

বিভিন্ন সংখ্যার তালিকার তালিকা হিসাবে একটি তালিকা সংরক্ষণ করার আরেকটি মার্জিত উপায় - যা এটি কোনও ফাইল থেকে পড়ে। (এখানে ফাইলটিতে ডেটাসেট ট্রেন রয়েছে) ট্রেনটি 50 টি সারি এবং 20 টি কলাম সহ একটি ডেটা সেট। অর্থাত্ ট্রেন [0] আমাকে একটি সিএসভি ফাইলের প্রথম সারি দেয়, ট্রেন [1] আমাকে ২ য় সারি দেয় এবং এ জাতীয় আরও কিছু করে। আমি ডেটাসেটকে 50 টি সারি দিয়ে একটি তালিকা হিসাবে আলাদা করতে আগ্রহী, কলাম 0 ব্যতীত, যা এখানে আমার বর্ণিত পরিবর্তনশীল, তাই অবশ্যই অরিজেনাল ট্রেনের ডেটাসেট থেকে সরিয়ে ফেলতে হবে, এবং তারপরে তালিকার পরে তালিকাটি স্কেলিং করতে হবে - অর্থাত্ তালিকার একটি তালিকা । এখানে কোডটি এটি করে।

মনে রাখবেন যে আমি কেবলমাত্র ব্যাখ্যামূলক ভেরিয়েবলগুলিতে আগ্রহী হওয়ায় আমি অভ্যন্তরীণ লুপটিতে "1" থেকে পড়ছি। এবং আমি অন্য লুপে এক্স 1 = [] পুনরায় আরম্ভ করি, অন্যথায় X2.append ([0: (লেন (ট্রেন [0]) - 1)]) এক্স 1 কে বারবার লিখবে - এ ছাড়া আরও স্মৃতিশক্তি কার্যকর।

X2=[]
for j in range(0,len(train)):
    X1=[]
    for k in range(1,len(train[0])):
        txt2=train[j][k]
        X1.append(txt2)
    X2.append(X1[0:(len(train[0])-1)])

4

তালিকা তৈরি করতে তালিকাগুলির নীচে বাক্য গঠন ব্যবহার করুন

     x = [[] for i in range(10)]

এটি 1-ডি তালিকা তৈরি করবে এবং এটিকে আরম্ভ করার জন্য [[সংখ্যা] এ নম্বর রাখবে এবং তালিকার দৈর্ঘ্যকে দৈর্ঘ্যের (দৈর্ঘ্যে) স্থাপন করবে

  • তালিকার তালিকা তৈরি করতে সিনট্যাক্সের নীচে ব্যবহার করুন।
    x = [[[0] for i in range(3)] for i in range(10)]

এটি 10 ​​* 3 মাত্রা এবং মান 0 দিয়ে তালিকাগুলির তালিকা আরম্ভ করবে

  • উপাদান অ্যাক্সেস / কারসাজি করতে
    x[1][5]=value

2

তাই আমি দ্রুততম উপায় পেতে কিছু গতির তুলনা করেছি। তালিকা বোধগম্যতা খুব দ্রুত। কাছাকাছি যাওয়ার একমাত্র উপায় হ'ল তালিকাগুলির নির্মাণকালে বাইটকোডকে নিরস্ত করা থেকে বিরত রাখা। আমার প্রথম প্রচেষ্টাটি নিম্নলিখিত পদ্ধতি ছিল যা নীতিগতভাবে দ্রুত হবে বলে মনে হয়:

l = [[]]
for _ in range(n): l.extend(map(list,l))

(দৈর্ঘ্যের 2 ** এন এর তালিকা তৈরি করে অবশ্যই) সংক্ষিপ্ত এবং দীর্ঘ উভয় (মিলিয়ন) উভয়ের তালিকার জন্য সময় নির্ধারিত অনুসারে এই নির্মাণটি তালিকা বোধগমের চেয়ে দ্বিগুণ ধীর।

আমার দ্বিতীয় চেষ্টাটি আমার জন্য তালিকার কনস্ট্রাক্টরকে কল করতে স্টারম্যাপ ব্যবহার করা ছিল, একটি নির্মাণ রয়েছে, যা শীর্ষ গতিতে তালিকার নির্মাণকারীকে চালিত করে বলে মনে হয়, তবে এখনও ধীর গতিতে, তবে কেবলমাত্র একটি ক্ষুদ্র পরিমাণে:

from itertools import starmap
l = list(starmap(list,[()]*(1<<n)))

মৃত্যুদন্ড কার্যকর করার জন্য পর্যাপ্ত আকর্ষণীয় পরামর্শ দেয় যে এটি চূড়ান্ত তালিকা কল যা স্টারম্যাপ সমাধানকে ধীর করে দেয়, কারণ তার মৃত্যুদন্ড কার্যকর করার সময়টি প্রায় গতির সাথে সমান:

l = list([] for _ in range(1<<n))

আমার তৃতীয় প্রয়াস এলো যখন আমি বুঝতে পারলাম যে তালিকা (()) এছাড়াও একটি তালিকা তৈরি করে, তাই আমি আগ্রহীভাবে সহজ চেষ্টা করেছিলাম:

l = list(map(list, [()]*(1<<n)))

তবে এটি স্টারম্যাপ কলের চেয়ে ধীর ছিল।

উপসংহার: গতি পাগল জন্য: তালিকা বোধগম্যতা ব্যবহার করবেন না। আপনার যদি করতে হয় তবে কেবলমাত্র কল করুন call বিল্টিন ব্যবহার করুন।

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