সংক্ষিপ্ত অজগর তালিকার প্রিপেন্ডিংয়ের আইডিয়োমেটিক সিনট্যাক্স কী?


542

list.append()একটি তালিকার শেষে যুক্ত করার জন্য সুস্পষ্ট পছন্দ। নিখোঁজ হওয়ার জন্য এখানে যুক্তিসঙ্গত ব্যাখ্যা দেওয়া হল list.prepend()। ধরে নিচ্ছি আমার তালিকাটি সংক্ষিপ্ত এবং পারফরম্যান্সের উদ্বেগগুলি নগন্য,

list.insert(0, x)

অথবা

list[0:0] = [x]

কথ্য?

উত্তর:


782

s.insert(0, x)ফর্ম সবচেয়ে সাধারণ।

আপনি যখনই এটি দেখতে পাচ্ছেন, তালিকার পরিবর্তে সংগ্রহগুলি.ডেক ব্যবহার করার বিষয়টি বিবেচনা করার সময় হতে পারে ।


9
"আপনি যখনই এটি দেখতে পাচ্ছেন তখন তালিকার পরিবর্তে সংগ্রহগুলি ব্যবহারের বিষয়ে বিবেচনা করার সময় আসবে।" কেন?
ম্যাট এম

6
@MattM। আপনি যদি কোনও তালিকার সামনের দিকে সন্নিবেশ করেন তবে অজগরকে অন্যান্য সমস্ত আইটেমকে এক স্থান এগিয়ে নিয়ে যেতে হবে, তালিকাগুলি "সামনের দিকে স্থান তৈরি করতে পারে না"। কালেকশনস.ডেক (ডাবল এন্ড কাত) এর "সামনের দিকে জায়গা তৈরি করার" পক্ষে সমর্থন রয়েছে এবং এক্ষেত্রে এটি আরও দ্রুত।
ফিজফো

265

আপনি যদি কার্যকরী উপায়ে যেতে পারেন তবে নিম্নলিখিতটি বেশ পরিষ্কার

new_list = [x] + your_list

অবশ্যই আপনি সন্নিবেশিত করেন নি xমধ্যে your_list, বরং আপনার সাথে একটি নতুন তালিকা তৈরি করেছেন xএটি preprended।


45
আপনি পর্যবেক্ষণ হিসাবে, এটি একটি তালিকা প্রস্তুত নয়। এটি একটি নতুন তালিকা তৈরি করছে। সুতরাং এটি প্রশ্নটি মোটেও সন্তুষ্ট করে না।
ক্রিস মরগান

111
যদিও এটি প্রশ্নটি সন্তুষ্ট করে না, এটি এটিকে ঘিরে ফেলে এবং এটি এই ওয়েবসাইটটির উদ্দেশ্য। মন্তব্যটির প্রশংসা করুন এবং আপনি ঠিক বলেছেন, কিন্তু লোকেরা যখন এটি অনুসন্ধান করে, এটি দেখার পক্ষে এটি সহায়ক।
dave4jr

2
এছাড়াও, আপনি যদি কোনও তালিকায় একটি তালিকা প্রিন্ট করতে চান তবে সন্নিবেশ ব্যবহার করা প্রত্যাশার মতো কাজ করবে না। কিন্তু এই পদ্ধতিটি করে!
Göta

89

সংক্ষিপ্ত অজগর তালিকার প্রিপেন্ডিংয়ের আইডিয়োমেটিক সিনট্যাক্স কী?

আপনি সাধারণত পাইথনের একটি তালিকাতে পুনরাবৃত্তভাবে সংশোধন করতে চান না।

যদি এটি সংক্ষিপ্ত হয় , এবং আপনি এটি খুব বেশি কিছু করছেন না ... তবে ঠিক আছে।

list.insert

list.insertএই ভাবে ব্যবহার করা যাবে।

list.insert(0, x)

তবে এটি অকার্যকর, কারণ পাইথন-এ, listপয়েন্টারগুলির একটি অ্যারে এবং পাইথনকে অবশ্যই তালিকার প্রতিটি পয়েন্টারটি নিতে হবে এবং প্রথম স্লটে আপনার অবজেক্টে পয়েন্টারটি সন্নিবেশ করতে একে একে নীচে সরানো উচিত, সুতরাং এটি সত্যই কেবল দক্ষ বরং আপনি চান হিসাবে সংক্ষিপ্ত তালিকা।

এটি সিপিথন উত্স থেকে একটি স্নিপেট রয়েছে যেখানে এটি প্রয়োগ করা হয়েছে - এবং আপনি দেখতে পাচ্ছেন যে, আমরা অ্যারের শেষে শুরু করি এবং প্রতিটি সন্নিবেশের জন্য সবকিছুকে এক এক করে সরিয়ে নিয়ে যাই:

for (i = n; --i >= where; )
    items[i+1] = items[i];

যদি আপনি এমন ধারক / তালিকা চান যা প্রিপেন্ডিং উপাদানগুলিতে দক্ষ হয় তবে আপনি একটি লিঙ্কযুক্ত তালিকা চান। পাইথনের একটি দ্বিগুণ লিঙ্কযুক্ত তালিকা রয়েছে, যা শুরুতে সন্নিবেশ করা যায় এবং দ্রুত শেষ হতে পারে - এটিকে বলা হয় এ deque

deque.appendleft

collections.dequeতালিকার অনেকগুলি পদ্ধতি রয়েছে। সম্পূর্ণ ব্যতীত লিসকভের পরিবর্তে স্থায়ী নয় এমনটি list.sortব্যতিক্রম ।dequelist

>>> set(dir(list)) - set(dir(deque))
{'sort'}

dequeএছাড়াও একটি হয়েছে appendleftপদ্ধতি (সেইসাথে popleft)। dequeএকটি ডবল শেষ হয়েছে কিউ এবং একটি দোকর-লিঙ্ক তালিকা - কোন ব্যাপার দৈর্ঘ্য, এটা সবসময় preprend কিছু সময় একই পরিমাণ সময় লাগে। বড় হে স্বরলিপিতে ও (1) বনাম ও (এন) তালিকার জন্য সময়। এখানে ব্যবহার:

>>> import collections
>>> d = collections.deque('1234')
>>> d
deque(['1', '2', '3', '4'])
>>> d.appendleft('0')
>>> d
deque(['0', '1', '2', '3', '4'])

deque.extendleft

এছাড়াও ডেকির extendleftপদ্ধতিটি প্রাসঙ্গিক , যা পুনরাবৃত্তভাবে পূর্বে সংশোধন করে:

>>> from collections import deque
>>> d2 = deque('def')
>>> d2.extendleft('cba')
>>> d2
deque(['a', 'b', 'c', 'd', 'e', 'f'])

নোট করুন যে প্রতিটি উপাদান একবারে একটি করে চাপিয়ে দেওয়া হবে, যাতে কার্যকরভাবে তাদের ক্রমটি বিপরীত হয়।

listবনাম অভিনয়deque

প্রথমে আমরা কিছু পুনরাবৃত্তি প্রিপেন্ডিং সেটআপ করি:

import timeit
from collections import deque

def list_insert_0():
    l = []
    for i in range(20):
        l.insert(0, i)

def list_slice_insert():
    l = []
    for i in range(20):
        l[:0] = [i]      # semantically same as list.insert(0, i)

def list_add():
    l = []
    for i in range(20):
        l = [i] + l      # caveat: new list each time

def deque_appendleft():
    d = deque()
    for i in range(20):
        d.appendleft(i)  # semantically same as list.insert(0, i)

def deque_extendleft():
    d = deque()
    d.extendleft(range(20)) # semantically same as deque_appendleft above

এবং কর্মক্ষমতা:

>>> min(timeit.repeat(list_insert_0))
2.8267281929729506
>>> min(timeit.repeat(list_slice_insert))
2.5210217320127413
>>> min(timeit.repeat(list_add))
2.0641671380144544
>>> min(timeit.repeat(deque_appendleft))
1.5863927800091915
>>> min(timeit.repeat(deque_extendleft))
0.5352169770048931

Deque অনেক দ্রুত। তালিকাগুলি আরও দীর্ঘ হওয়ার সাথে সাথে আমি আরও ভাল পারফরম্যান্সের প্রত্যাশা করব। আপনি যদি ডেকের ব্যবহার করতে পারেন তবে আপনি extendleftসম্ভবত সেরা অভিনয়টি পাবেন।


57

যদি কেউ আমার মতো এই প্রশ্নটি খুঁজে পান তবে প্রস্তাবিত পদ্ধতির আমার সম্পাদনা পরীক্ষাগুলি এখানে রয়েছে:

Python 2.7.8

In [1]: %timeit ([1]*1000000).insert(0, 0)
100 loops, best of 3: 4.62 ms per loop

In [2]: %timeit ([1]*1000000)[0:0] = [0]
100 loops, best of 3: 4.55 ms per loop

In [3]: %timeit [0] + [1]*1000000
100 loops, best of 3: 8.04 ms per loop

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


11
সেই পরীক্ষাটি থেকে একটি জিনিস যা অনুপস্থিত তা হ'ল জটিলতা। যদিও প্রথম দুটি বিকল্পের ধ্রুবক জটিলতা রয়েছে (তালিকার মধ্যে আরও উপাদান থাকা সত্ত্বেও এটি ধীর হয় না), তৃতীয়টির ক্ষেত্রে রৈখিক জটিলতা রয়েছে (তালিকার উপাদানগুলির পরিমাণের উপর নির্ভর করে এটি ধীর হয়ে যায়), কারণ এটি সর্বদা পুরো তালিকাটি অনুলিপি করতে হবে। তালিকার আরও উপাদান সহ, ফলাফলটি আরও খারাপ হতে পারে।
ডাকারন

6
@ ডাকারন আমি মনে করি আপনি এটি সম্পর্কে ভুল wrong বেশ কয়েকটি সূত্র list.insert এর জন্য লিনিয়ার জটিলতার উদ্ধৃতি দেয়, উদাহরণস্বরূপ এই দুর্দান্ত টেবিল এবং প্রশ্নকর্তার সাথে যুক্ত যুক্তিসঙ্গত ব্যাখ্যা দ্বারা বোঝানো হয়েছে। আমার সন্দেহ হয় সিপিথন প্রথম দুটি ক্ষেত্রে তালিকায় মেমরির প্রতিটি উপাদান পুনরায় বরাদ্দ করছে, সুতরাং এই তিনটিরই সম্ভবত লিনিয়ার জটিলতা রয়েছে। আমি কোডটি আসলে দেখিনি বা নিজে নিজে এটি পরীক্ষা করে দেখিনি, তবে এই উত্সগুলি ভুল হলে দুঃখিত sorry কালেকশন.ডেক.এপেন্ডেলফ্টের মধ্যে আপনি যে লিনিয়ার জটিলতা নিয়ে কথা বলছেন তা আছে।
টিসি প্রক্টর 21

@ ডাকারন সত্য নয়, এগুলির সকলেরই সমতুল্য জটিলতা রয়েছে। যদিও .insertএবং স্থানে[0:0] = [0] কাজ করে , তবুও তাদের পুরো বাফারটি পুনরায় বরাদ্দ করতে হবে।
juanpa.arrivillaga

এই মানদণ্ডগুলি খারাপ। প্রাথমিক তালিকাটি পৃথক সেটআপ ধাপে তৈরি করা উচিত, সময়সইয়ের অংশ নয়। এবং সর্বশেষে 1000001 দীর্ঘ একটি নতুন তালিকা তৈরি করে, তাই অন্য দুটি স্থান পরিবর্তনকারী জায়গাগুলির সাথে তুলনা করা হ'ল আপেল এবং কমলা।
Wim
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.