পাইথনের তালিকা কীভাবে কার্যকর করা হয়?


181

এটি কি একটি লিঙ্কযুক্ত তালিকা, একটি অ্যারে? আমি আশেপাশে অনুসন্ধান করেছি এবং কেবল লোকেরা অনুমান করতে দেখেছি। সোর্স কোডটি দেখার জন্য আমার সি জ্ঞান যথেষ্ট ভাল নয়।

উত্তর:


56

এটি একটি গতিশীল অ্যারে । ব্যবহারিক প্রমাণ: সূচক নির্বিশেষে একই সময়ে সূচীকরণ (অবশ্যই খুব ছোট পার্থক্য সহ (0.0013 µ সেকস!)) লাগে:

...>python -m timeit --setup="x = [None]*1000" "x[500]"
10000000 loops, best of 3: 0.0579 usec per loop

...>python -m timeit --setup="x = [None]*1000" "x[0]"
10000000 loops, best of 3: 0.0566 usec per loop

আমি অবাক হয়ে যাব যদি আয়রন পাইথন বা জাইথন ​​লিঙ্কযুক্ত তালিকাগুলি ব্যবহার করে - তারা তালিকাগুলি অ্যারে হিসাবে এই ধারণার উপর নির্মিত অনেকগুলি বহুল ব্যবহৃত গ্রন্থাগারের কার্যকারিতা নষ্ট করে দেবে।


1
@ রাল্ফ: আমি জানি আমার সিপিইউ (বেশিরভাগ অন্যান্য হার্ডওয়্যারও, সে ক্ষেত্রে) পুরানো এবং কুকুর ধীর - উজ্জ্বল দিক থেকে, আমি ধরে নিতে পারি যে আমার পক্ষে দ্রুত

87
@ ডেলানন: -1 আপনার "ব্যবহারিক প্রমাণ" একটি বাজে কথা, 6 টি উপগ্রহ যেমন রয়েছে। x=[None]*1000সম্ভাব্য তালিকার অ্যাক্সেসের পার্থক্যের পরিবর্তে অসম্পূর্ণতার পরিমাপ রেখে প্রায় 98% সময় ব্যয় করা হয় । আপনার -s "x=[None]*100" "x[0]"
সূচনাটি

26
দেখায় যে এটি কোনও লিঙ্কযুক্ত তালিকার একটি নিষ্পাপ বাস্তবায়ন নয়। এটি একটি অ্যারে নিশ্চিতভাবে দেখায় না।
মাইকেল মায়ার

6
আপনি এটি সম্পর্কে এখানে পড়তে পারেন: docs.python.org/2/faq/design.html#how-are-lists- বাস্তবায়ন
CCoder

3
কেবলমাত্র লিঙ্কযুক্ত তালিকা এবং অ্যারের চেয়ে অনেক বেশি কাঠামো রয়েছে, তাদের মধ্যে সিদ্ধান্ত নেওয়ার জন্য সময় নির্ধারণের কোনও ব্যবহারিক ব্যবহার নয়।
রস হেমসলে

236

সি কোডটি বেশ সহজ, আসলে। একটি ম্যাক্রো প্রসারিত করা এবং কিছু অপ্রাসঙ্গিক মন্তব্য ছাঁটাই করা, মূল কাঠামোটি রয়েছে listobject.h, যা একটি তালিকা হিসাবে সংজ্ঞায়িত করে:

typedef struct {
    PyObject_HEAD
    Py_ssize_t ob_size;

    /* Vector of pointers to list elements.  list[0] is ob_item[0], etc. */
    PyObject **ob_item;

    /* ob_item contains space for 'allocated' elements.  The number
     * currently in use is ob_size.
     * Invariants:
     *     0 <= ob_size <= allocated
     *     len(list) == ob_size
     *     ob_item == NULL implies ob_size == allocated == 0
     */
    Py_ssize_t allocated;
} PyListObject;

PyObject_HEADএকটি রেফারেন্স গণনা এবং একটি ধরণের সনাক্তকারী থাকে contains সুতরাং, এটি সামগ্রিকভাবে সঞ্চারিত একটি ভেক্টর / অ্যারে। এই জাতীয় অ্যারেটি পূর্ণ হওয়ার পরে পুনরায় আকার দেওয়ার কোড listobject.c। এটি আসলে অ্যারের দ্বিগুণ হয় না, বরাদ্দ দিয়ে বৃদ্ধি করে

new_allocated = (newsize >> 3) + (newsize < 9 ? 3 : 6);
new_allocated += newsize;

প্রতিবারের ক্ষমতায়, যেখানে newsizeঅনুরোধ করা আকারটি (অগত্যা নয় allocated + 1কারণ আপনি extendনির্বিচারে সংখ্যক উপাদানের appendদ্বারা একে একে 'ইনগ্রেড করার পরিবর্তে পারেন ')।

আরও দেখুন পাইথন প্রায়শই জিজ্ঞাসিত প্রশ্নাবলী


6
সুতরাং, অজগর তালিকার উপর পুনরাবৃত্তি যখন এটি লিঙ্কযুক্ত তালিকার মতো ধীর হয় কারণ প্রতিটি প্রবেশ কেবলমাত্র পয়েন্টার তাই প্রতিটি উপাদান সম্ভবত ক্যাশে মিসের কারণ হতে পারে entry
Kr0e

9
@ Kr0e: যদি পরবর্তী উপাদানগুলি আসলে একই জিনিস হয় তবে নয় :) তবে আপনার যদি ছোট / ক্যাশে-বন্ধুত্বপূর্ণ ডেটা স্ট্রাকচারের প্রয়োজন হয় তবে arrayমডিউল বা নুমপি পছন্দ করা উচিত।
ফ্রেড ফু

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

35

সিপিথনে, তালিকাগুলি পয়েন্টারগুলির অ্যারে হয়। পাইথনের অন্যান্য বাস্তবায়নগুলি এগুলি বিভিন্ন উপায়ে সঞ্চয় করতে পছন্দ করতে পারে।


32

এটি বাস্তবায়ন নির্ভর, কিন্তু আইআইআরসি:

  • সিপিথন পয়েন্টারগুলির একটি অ্যারে ব্যবহার করে
  • জাইথন ​​একটি ব্যবহার করে ArrayList
  • আয়রন পাইথন দৃশ্যত একটি অ্যারেও ব্যবহার করে। আপনি খুঁজে পেতে উত্স কোডটি ব্রাউজ করতে পারেন ।

এইভাবে তাদের সকলের ও (1) এলোমেলো অ্যাক্সেস রয়েছে।


1
পাইথন ইন্টারপ্রেটারের মতো বাস্তবায়ন নির্ভরশীল যা লিঙ্কযুক্ত তালিকাগুলি হিসাবে তালিকাগুলি কার্যকর করে তা অজগর ভাষার বৈধ প্রয়োগ হতে পারে? অন্য কথায়: ও (1) তালিকায় এলোমেলো প্রবেশের নিশ্চয়তা নেই? এটি কি প্রয়োগের বিশদ নির্ভর না করে দক্ষ কোড লেখা অসম্ভব করে না?
sepp2k

2
@ সেপ আমি বিশ্বাস করি পাইথনের তালিকাগুলি কেবল সংগ্রহের আদেশ দেওয়া হয়েছে; উক্ত বাস্তবায়নের বাস্তবায়ন এবং / বা কার্য সম্পাদনের প্রয়োজনীয়তাগুলি স্পষ্টভাবে বলা হয়নি
নুল ইউজার এক্সসেপশন

6
@ এসপিপি ২ কে: যেহেতু পাইথনের আসলে কোনও স্ট্যান্ডার্ড বা আনুষ্ঠানিক স্পেসিফিকেশন নেই (যদিও এখানে কিছু ডকুমেন্টেশন রয়েছে যা "... এর গ্যারান্টিযুক্ত ..."), আপনি "এটি হিসাবে 100% নিশ্চিত হতে পারবেন না কিছু কাগজের গ্যারান্টিযুক্ত "। তবে যেহেতু O(1)তালিকা সূচকের জন্য একটি সাধারণ সাধারণ এবং বৈধ অনুমান, তাই কোনও বাস্তবায়নই এটি ভেঙে ফেলার সাহস করবে না।

@ পল এটি তালিকার অন্তর্নিহিত বাস্তবায়ন কীভাবে করা উচিত সে সম্পর্কে কিছুই জানায় না।
নালুউজারএক্সেপশন

বিগ হে চলমান সময়গুলি নির্দিষ্ট করার জন্য এটি ঘটে না। ভাষার সিনট্যাক্সের স্পেসিফিকেশনটি বাস্তবায়নের বিশদ হিসাবে একই জিনিসটিকে অগত্যা বোঝায় না, এটি প্রায়শই ঘটে থাকে।
পল ম্যাকমিলান

26

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

তালিকা অবজেক্ট সি কাঠামো

সিপিথনে একটি তালিকা অবজেক্ট নিম্নলিখিত সি কাঠামোর দ্বারা প্রতিনিধিত্ব করা হয়। ob_itemতালিকার উপাদানগুলির পয়েন্টারের একটি তালিকা। বরাদ্দ হ'ল মেমরিতে বরাদ্দ স্লটের সংখ্যা ots

typedef struct {
    PyObject_VAR_HEAD
    PyObject **ob_item;
    Py_ssize_t allocated;
} PyListObject;

বরাদ্দ স্লট এবং তালিকার আকারের মধ্যে পার্থক্যটি লক্ষ্য করা গুরুত্বপূর্ণ। একটি তালিকা আকার হিসাবে একই len(l)। বরাদ্দ স্লট সংখ্যা মেমরি বরাদ্দ করা হয় কি। প্রায়শই, আপনি দেখতে পাবেন যে বরাদ্দ করা আকারের চেয়ে বড় হতে পারে। এই reallocতালিকায় নতুন উপাদান যুক্ত হওয়ার সময় কল করা দরকার এড়াতে ।

...

পরিশেষে

আমরা লিস্টে একটি পূর্ণসংখ্যা যোগ: l.append(1)। কি ঘটেছে?
এখানে চিত্র বর্ণনা লিখুন

আমরা আরও একটি উপাদান যোগ করে অবিরত: l.append(2)list_resizen + 1 = 2 দিয়ে ডাকা হয় তবে বরাদ্দ আকার 4 হওয়ায় বেশি মেমরি বরাদ্দ করার দরকার হয় না। যখন আমরা 2 একাধিক পূর্ণসংখ্যার যোগ একই জিনিস ঘটে: l.append(3), l.append(4)। নিম্নলিখিত চিত্রটি এখন পর্যন্ত আমাদের কী রয়েছে তা দেখায়।

এখানে চিত্র বর্ণনা লিখুন

...

সন্নিবেশ

আসুন 1 পজিশনে একটি নতুন পূর্ণসংখ্যা (5) প্রবেশ করান: l.insert(1,5)এবং অভ্যন্তরীণভাবে কী ঘটে তা দেখুন।এখানে চিত্র বর্ণনা লিখুন

...

পপ

যখন আপনি শেষ উপাদান পপ: l.pop(), listpop()বলা হয়। list_resizeভিতরে বলা হয় listpop()এবং নতুন আকার যদি বরাদ্দ করা মাপের অর্ধেকের কম হয় তবে তালিকাটি সঙ্কুচিত হবে।এখানে চিত্র বর্ণনা লিখুন

আপনি যে স্লট 4 টি এখনও পূর্ণসংখ্যার দিকে নির্দেশ করে তা পর্যবেক্ষণ করতে পারেন তবে গুরুত্বপূর্ণ বিষয়টি এখন তালিকার আকার যা এখন 4 Let's আরও একটি উপাদান পপ করুন। ভিতরেlist_resize() , আকার - 1 = 4 - 1 = 3 বরাদ্দ স্লটের অর্ধেকেরও কম তাই তালিকাটি 6 টি স্লটে সঙ্কুচিত হয়ে তালিকার নতুন আকার এখন 3 হয় 3

আপনি স্লট 3 এবং 4 টি এখনও কিছু পূর্ণসংখ্যার দিকে নির্দেশ করতে পারেন তবে গুরুত্বপূর্ণ বিষয়টি তালিকার আকার যা এখন 3।এখানে চিত্র বর্ণনা লিখুন

...

সরান পাইথন তালিকা বস্তুর কোনও নির্দিষ্ট উপাদানের সরানোর জন্য একটি পদ্ধতি রয়েছে: l.remove(5)এখানে চিত্র বর্ণনা লিখুন


ধন্যবাদ, আমি এখন তালিকার লিংক অংশটি আরও বুঝতে পারি । পাইথন তালিকা একটি aggregation, না composition। আমার মনে হয় কম্পোজিশনের একটি তালিকাও রয়েছে।
শুভা

22

ডকুমেন্টেশন অনুযায়ী ,

পাইথনের তালিকাগুলি সত্যিই পরিবর্তনশীল-দৈর্ঘ্যের অ্যারে, লিস্প-স্টাইলে সংযুক্ত তালিকা নয়।


5

অন্যরা যেমন উপরে বলেছে, তালিকাগুলি (যখন প্রশংসনীয়ভাবে বড় হয়) একটি নির্দিষ্ট পরিমাণ জায়গা বরাদ্দ করে প্রয়োগ করা হয়, এবং যদি সেই স্থানটি পূরণ করা যায় তবে একটি বৃহত পরিমাণে স্থান বরাদ্দ করে এবং উপাদানগুলির অনুলিপি করে।

কেন সাধনতার ক্ষতি ছাড়াই পদ্ধতিটি ও (1) অ্যামরুটাইজড, তা বোঝার জন্য ধরে নিন যে আমরা একটি = 2। N উপাদান .োকিয়েছি এবং এখন আমাদের টেবিলটি 2 ^ (এন + 1) আকারে দ্বিগুণ করতে হবে। এর অর্থ আমরা বর্তমানে ২ ^ (n + 1) অপারেশন করছি। শেষ অনুলিপি, আমরা 2 ^ n অপারেশন করেছি। এর আগে আমরা 2 ^ (এন -1) করেছি ... সমস্ত পথে 8,4,2,1 এ গিয়েছি। এখন, আমরা যদি এগুলি যুক্ত করি তবে আমরা 1 + 2 + 4 + 8 + ... + 2 ^ (এন + 1) = 2 ^ (এন + 2) - 1 <4 * 2 ^ n = ও (2 ^) পাই n) = হে (ক) মোট সন্নিবেশ (যেমন ও (1) মোড়িত সময়)। এছাড়াও, এটি লক্ষ করা উচিত যে টেবিলটি মুছে ফেলতে দেয় তবে টেবিলটি সঙ্কুচিত করতে হবে অন্য কোনও ফ্যাক্টর (উদাহরণস্বরূপ 3x)


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

1

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

list_one = [1,2,3,4]

my_list = list_one

#my_list: [1,2,3,4]

my_list.append("new")

#my_list: [1,2,3,4,'new']
#list_one: [1,2,3,4,'new']

আমরা সংযোজন করি my_listতবে আমাদের মূল তালিকাটি পরিবর্তিত হয়েছে। তার মানে এর তালিকাটি তার উল্লেখ হিসাবে একটি অনুলিপি তালিকা হিসাবে বরাদ্দ করে নি।


0

সিপিথনে তালিকাকে ডায়নামিক অ্যারে হিসাবে প্রয়োগ করা হয়, এবং সেইজন্য যখন আমরা সেই সময় সংযোজন করি তখন কেবল একটি ম্যাক্রো যোগ করা হয় না তবে আরও কিছু স্থান বরাদ্দ করা হয় যাতে প্রতিটি সময় নতুন স্থান যুক্ত না হয়।

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