কেন এটি list.join (স্ট্রিং) এর পরিবর্তে স্ট্রিং.জাইন (তালিকা)?


1761

এটি আমাকে সর্বদা বিভ্রান্ত করেছে। দেখে মনে হচ্ছে এটি সুন্দর হবে:

my_list = ["Hello", "world"]
print(my_list.join("-"))
# Produce: "Hello-world"

এই তুলনায়:

my_list = ["Hello", "world"]
print("-".join(my_list))
# Produce: "Hello-world"

এটির মতো কোনও নির্দিষ্ট কারণ আছে?


1
সহজ স্মৃতি এবং বোঝার জন্য, -ঘোষণা করে যে আপনি একটি তালিকায় যোগ দিচ্ছেন এবং একটি স্ট্রিংয়ে রূপান্তর করছেন t এর ফলাফল ওরিয়েন্টেড।
ক্যালকুলাস

11
@ জাওসাউ: এটি কেবল মেমকে আরও বিভ্রান্ত করে।
einpoklum

32
আমি মনে করি সংক্ষিপ্ত উত্তরটি হ'ল এটি কারণ পাইথনের টাইপ সিস্টেমটি যথেষ্ট শক্তিশালী নয় এবং strপ্রতিটি পুনরাবৃত্ত টাইপটিতে এটি প্রয়োগ করার চেয়ে একবার এই কার্যকারিতাটি কার্যকর করা সহজ হয়েছিল ।
বলপয়েন্টবেন

3
আমি মনে করি আসল ধারণাটি হ'ল যেহেতু যোগদান () একটি স্ট্রিং ফিরিয়ে দেয়, এটি স্ট্রিং প্রসঙ্গ থেকে কল করতে হবে। তালিকায় যোগ () যুক্ত করা একটি টোনটি বোঝায় না যে তালিকাটি বস্তুর একটি ধারক এবং কেবল স্ট্রিংগুলির সাথে নির্দিষ্ট ওয়ান-অফ ফাংশন থাকা উচিত নয়।
জোশুয়া বার্নস

উত্তর:


1247

এটি কারণ যে কোনও পুনরাবৃত্তীয় যোগ দিতে পারে (যেমন, তালিকা, টিপল, ডিক, সেট), তবে ফলাফল এবং "সংযুক্তকারী" অবশ্যই স্ট্রিং হওয়া উচিত

উদাহরণ স্বরূপ:

'_'.join(['welcome', 'to', 'stack', 'overflow'])
'_'.join(('welcome', 'to', 'stack', 'overflow'))
'welcome_to_stack_overflow'

স্ট্রিং ছাড়া অন্য কিছু ব্যবহার করা নিম্নলিখিত ত্রুটিটিকে বাড়িয়ে তুলবে:

প্রকারের ত্রুটি: সিকোয়েন্স আইটেম 0: প্রত্যাশিত স্ট্রান্স উদাহরণ, int পাওয়া গেছে


55
কোডওয়ালাভাবে এটি বোধগম্য হলেও আমি ধারণাগতভাবে সম্মত নই। আমার কাছে আরও বেশি পদ্ধতিগত শোনার পরে list.join(string)আরও একটি অবজেক্ট-ভিত্তিক দৃষ্টিভঙ্গি উপস্থিত string.join(list)হয়।
এডুয়ার্ডো পিগনেটেলি

21
সুতরাং কেন এটি পুনরাবৃত্তির উপর প্রয়োগ করা হয় না?
স্টেইন শ্যাট

10
@ টাইমশীপ: পুনরাবৃত্ত হওয়া সত্ত্বেও পূর্ণসংখ্যার একটি তালিকার অর্থবহ সংযোগ নেই।
পুনরাবৃত্তি

16
আমি ব্যবহার করার চেষ্টা করেছি print(str.join('-', my_list))এবং এটি কাজ করে, আরও ভাল লাগে।
পিমজেক

13
@ টাইমশীপ যেহেতু পুনরাবৃত্তযোগ্য কোনও কংক্রিটের ধরণের নয়, পুনরাবৃত্তযোগ্য একটি ইন্টারফেস, কোনও __iter__পদ্ধতি যা সংজ্ঞায়িত করে । সমস্ত পুনরাবৃত্তিকে প্রয়োগ করার জন্য প্রয়োজনীয় joinএকটি সাধারণ ইন্টারফেসকে জটিল করে তুলবে (যা অ-স্ট্রিংগুলির উপরে পুনরাবৃত্তিগুলিও কভার করে) খুব বিশেষ ব্যবহারের ক্ষেত্রে। joinস্ট্রিনগুলির পক্ষে "সমস্যাহীন" আদেশের মূল্যে এই সমস্যাটিকে পাশ-ধাপে সংজ্ঞায়িত করা হচ্ছে। প্রথম যুক্তিটি পুনরাবৃত্তিযোগ্য এবং দ্বিতীয় (optionচ্ছিক একটি) সংযুক্তকারী স্ট্রিংয়ের সাথে এটি একটি ফাংশন রাখা আরও ভাল পছন্দ হতে পারে - তবে সেই জাহাজটি যাত্রা করেছিল।
ব্যবহারকারী 4815162342

318

এটি স্ট্রিং পদ্ধতিগুলিতে আলোচনা করা হয়েছিল ... অবশেষে পাইথন-দেব আচিভে থ্রেড করা হয়েছিল এবং গুইডো গ্রহণ করেছিলেন। এই থ্রেডটি ১৯৯৯ সালের জুনে শুরু str.joinহয়েছিল এবং পাইথন ১.6-এ অন্তর্ভুক্ত হয়েছিল যা সেপ্টেম্বর 2000 এ প্রকাশিত হয়েছিল (এবং ইউনিকোড সমর্থিত)। পাইথন 2.0 ( strসহ সমর্থিত পদ্ধতিগুলি join) 2000 সালের অক্টোবরে প্রকাশিত হয়েছিল।

  • এই থ্রেডে প্রস্তাবিত চারটি বিকল্প ছিল:
    • str.join(seq)
    • seq.join(str)
    • seq.reduce(str)
    • join একটি অন্তর্নির্মিত ফাংশন হিসাবে
  • গুইডো কেবল listগুলি, tupleগুলি নয়, সমস্ত ক্রম / পুনরাবৃত্তিকে সমর্থন করতে চেয়েছিলেন ।
  • seq.reduce(str) নতুন আগতদের পক্ষে কঠিন।
  • seq.join(str) ক্রম থেকে স্ট্রিং / ইউনিকোডে অপ্রত্যাশিত নির্ভরতার পরিচয় দেয় introdu
  • join()একটি অন্তর্নির্মিত ফাংশন হিসাবে কেবল নির্দিষ্ট ডেটা ধরণের সমর্থন করবে। সুতরাং বিল্ট ইন নেমস্পেস ব্যবহার করা ভাল নয়। যদি join()অনেকগুলি ডেটাটাইপ সমর্থন করে তবে অনুকূলিতকরণ বাস্তবায়ন তৈরি করা কঠিন, যদি __add__পদ্ধতিটি ব্যবহার করে প্রয়োগ করা হয় তবে এটি ও (N²)।
  • বিভাজক স্ট্রিং ( sep) বাদ দেওয়া উচিত নয়। সুস্পষ্ট বর্ণিত চেয়ে ভাল।

এই থ্রেডে দেওয়া অন্য কোনও কারণ নেই।

এখানে কিছু অতিরিক্ত চিন্তা (আমার নিজস্ব এবং আমার বন্ধুর) রয়েছে:

  • ইউনিকোড সমর্থন আসছিল, তবে এটি চূড়ান্ত হয়নি। তখন ইউটিএফ -8 ইউসিএস 2/4 প্রতিস্থাপনের বিষয়ে সবচেয়ে বেশি সম্ভাবনা ছিল। ইউটিএফ -8 স্ট্রিংয়ের মোট বাফার দৈর্ঘ্য গণনা করার জন্য এটি অক্ষর কোডিং বিধি জানতে হবে।
  • সেই সময় পাইথন ইতিমধ্যে একটি সাধারণ সিকোয়েন্স ইন্টারফেস নিয়ম নিয়ে সিদ্ধান্ত নিয়েছিল যেখানে কোনও ব্যবহারকারী সিকোয়েন্স-এর মতো (পুনরাবৃত্ত) শ্রেণি তৈরি করতে পারে। তবে পাইথন অন্তর্নির্মিত প্রকারগুলি ২.২ অবধি বাড়ানো সমর্থন করেনি। সেই সময় বেসিক পুনরাবৃত্ত শ্রেণি সরবরাহ করা কঠিন ছিল (যা অন্য মন্তব্যে উল্লেখ করা হয়েছে)।

গিডোর সিদ্ধান্তটি historical তিহাসিক মেলটিতে রেকর্ড করা হয়েছে , সিদ্ধান্ত নিয়ে str.join(seq):

মজার, তবে এটা ঠিক মনে হচ্ছে! ব্যারি, এর জন্য যাও ... -
গুইডো ভ্যান রসুম


251

কারণ join()পদ্ধতিটি স্ট্রিং ক্লাসের পরিবর্তে তালিকার শ্রেণীর পরিবর্তে?

আমি এটা মজার দেখতে সম্মত।

Http://www.faqs.org/docs/diveintopython/odbchelper_join.html দেখুন :

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

--- মার্ক পিলগ্রিম, পাইথনে ডুব দিন


12
পাইথন 3 stringলাইব্রেরি সমস্ত অপ্রয়োজনীয় strপদ্ধতি সরিয়ে ফেলেছে , সুতরাং আপনি আর ব্যবহার করতে পারবেন না string.join()। ব্যক্তিগতভাবে, আমি কখনই এটিকে 'মজাদার' মনে করি নি, এটি সঠিক ধারণা দেয়, কারণ আপনি কেবল তালিকাগুলির চেয়ে আরও অনেক কিছুতে যোগদান করতে পারেন, তবে যোগদানকারীটি সর্বদা একটি স্ট্রিং!
মার্টিজন পিটারস

67

আমি সম্মত হই যে এটি প্রথমে প্রতিদ্বন্দ্বী, তবে এর একটি ভাল কারণ আছে। যোগদান কোনও তালিকার একটি পদ্ধতি হতে পারে না কারণ:

  • এটি অবশ্যই বিভিন্ন পুনরাবৃত্তির জন্য কাজ করতে পারে (টিপলস, জেনারেটর, ইত্যাদি)
  • স্ট্রিং বিভিন্ন ধরণের মধ্যে এটির অবশ্যই আলাদা আচরণ থাকতে হবে।

এখানে দুটি যুক্ত হওয়ার পদ্ধতি রয়েছে (পাইথন 3.0):

>>> b"".join
<built-in method join of bytes object at 0x00A46800>
>>> "".join
<built-in method join of str object at 0x00A28D40>

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


45

এর string.join(list)বদলে কেন list.join(string)?

এটি কারণ joinএকটি "স্ট্রিং" পদ্ধতি! এটি যে কোনও পুনরাবৃত্তীয় থেকে একটি স্ট্রিং তৈরি করে। যদি আমরা তালিকাগুলিতে পদ্ধতিটি আটকে থাকি, যখন আমাদের তালিকাগুলি তালিকাগুলি না থাকে তখন কী হবে?

আপনি যদি স্ট্রিং একটি tuple আছে? এটি যদি কোনও listপদ্ধতি ছিল listতবে উপাদানগুলিকে একক স্ট্রিংয়ে যোগ দেওয়ার আগে আপনাকে প্রতিটি স্ট্রিংয়ের পুনরুক্তি করতে হবে ! উদাহরণ স্বরূপ:

some_strings = ('foo', 'bar', 'baz')

আসুন আমাদের নিজস্ব তালিকাতে যোগদানের পদ্ধতিটি রোল করুন:

class OurList(list): 
    def join(self, s):
        return s.join(self)

এবং এটি ব্যবহার করার জন্য, নোট করুন যে আমাদের প্রথমে প্রতিটি পুনরাবৃত্তিযোগ্য থেকে সেই পুনরাবৃত্তের স্ট্রিংগুলিতে যোগ দিতে একটি তালিকা তৈরি করতে হবে, মেমরি এবং প্রক্রিয়াকরণ শক্তি উভয়ই নষ্ট করে:

>>> l = OurList(some_strings) # step 1, create our list
>>> l.join(', ') # step 2, use our list join method!
'foo, bar, baz'

সুতরাং আমরা দেখতে পাচ্ছি যে আমাদের বিল্টিন স্ট্রিং পদ্ধতিটি ব্যবহার না করে আমাদের তালিকা পদ্ধতিটি ব্যবহার করতে আমাদের একটি অতিরিক্ত পদক্ষেপ যুক্ত করতে হবে:

>>> ' | '.join(some_strings) # a single step!
'foo | bar | baz'

জেনারেটরদের জন্য পারফরম্যান্স ক্যাভেট

অ্যালগরিদম পাইথন চূড়ান্ত স্ট্রিংটি তৈরি করতে ব্যবহার করে str.joinআসলে পুনরাবৃত্ত হতে পারে পুনরাবৃত্তিযোগ্য দু'বার, সুতরাং আপনি যদি এটি কোনও জেনারেটর এক্সপ্রেশন সরবরাহ করেন তবে এটি চূড়ান্ত স্ট্রিং তৈরি করার আগে এটি প্রথমে একটি তালিকাতে পরিণত করতে হবে।

সুতরাং, জেনারেটরগুলির কাছাকাছি যাওয়ার সময় সাধারণত তালিকা বোধের চেয়ে ভাল, str.joinএটি একটি ব্যতিক্রম:

>>> import timeit
>>> min(timeit.repeat(lambda: ''.join(str(i) for i in range(10) if i)))
3.839168446022086
>>> min(timeit.repeat(lambda: ''.join([str(i) for i in range(10) if i])))
3.339879313018173

তবুও, str.joinঅপারেশনটি এখনও শব্দার্থগতভাবে একটি "স্ট্রিং" অপারেশন, সুতরাং এটি strবিবিধ পুনরাবৃত্তের তুলনায় বস্তুটিতে থাকাটি এখনও বোধগম্য ।


24

এটিকে বিভক্ত করার প্রাকৃতিক অরথোগোনাল অপারেশন হিসাবে ভাবেন।

আমি বুঝতে পারি কেন এটি পুনরাবৃত্তিযোগ্য কোনও কিছুর জন্য প্রযোজ্য এবং তাই কেবলমাত্র তালিকায় সহজেই প্রয়োগ করা যায় না ।

পঠনযোগ্যতার জন্য, আমি এটি ভাষাতে দেখতে চাই তবে আমি মনে করি না যে এটি বাস্তবে সম্ভব - যদি পুনরুক্তি একটি ইন্টারফেস হয় তবে এটি ইন্টারফেসে যুক্ত হতে পারে তবে এটি কেবল একটি সম্মেলন এবং তাই এর কোনও কেন্দ্রীয় উপায় নেই এটি পুনরাবৃত্তযোগ্য জিনিসগুলির সেটগুলিতে যুক্ত করুন।


13

মূলত কারণ এ এর ​​ফলাফল someString.join()একটি স্ট্রিং।

ক্রম (তালিকা বা tuple বা যাই হোক না কেন) ফলাফল প্রদর্শিত হবে না, কেবল একটি স্ট্রিং। কারণ ফলাফলটি একটি স্ট্রিং, এটি স্ট্রিংয়ের একটি পদ্ধতি হিসাবে বোধ করে।


10

- "-" তে যোগ দিন (মাই_লিস্ট) ঘোষণা করে যে আপনি উপাদানগুলিকে তালিকায় যোগ দিয়ে একটি স্ট্রিংয়ে রূপান্তর করছেন। এর ফলাফল-ভিত্তিক ((কেবল সহজ স্মৃতি এবং বোঝার জন্য)

আপনার রেফারেন্সের জন্য আমি মেথড_এফ_ স্ট্রিংয়ের একটি সম্পূর্ণ চিটশিট তৈরি করি।

string_methonds_44 = {
    'convert': ['join','split', 'rsplit','splitlines', 'partition', 'rpartition'],
    'edit': ['replace', 'lstrip', 'rstrip', 'strip'],
    'search': ['endswith', 'startswith', 'count', 'index', 'find','rindex', 'rfind',],
    'condition': ['isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isnumeric','isidentifier',
                  'islower','istitle', 'isupper','isprintable', 'isspace', ],
    'text': ['lower', 'upper', 'capitalize', 'title', 'swapcase',
             'center', 'ljust', 'rjust', 'zfill', 'expandtabs','casefold'],
    'encode': ['translate', 'maketrans', 'encode'],
    'format': ['format', 'format_map']}

3

দুজনেই ভাল লাগছে না।

স্ট্রিং.জোঁইন (এক্সএস, ডিলিমিট) মানে স্ট্রিং মডিউলটি কোনও তালিকার অস্তিত্ব সম্পর্কে সচেতন, যার কোনও ব্যবসায় নেই, কারণ স্ট্রিং মডিউলটি কেবল স্ট্রিং দিয়ে কাজ করে।

list.join (ডিলিমিট) কিছুটা ভাল, কারণ আমরা স্ট্রিংগুলিকে একটি মৌলিক ধরণের (এবং ভাষাগতভাবে বলতে গেলে, তারা) অভ্যস্ত। তবে এর অর্থ হ'ল যোগদানকে গতিশীলভাবে প্রেরণ করা দরকার কারণ a.split("\n")পাইথন সংকলকটির স্বেচ্ছাসেবী প্রেক্ষাপটে সম্ভবত কী কী তা জানে না এবং এটি সন্ধান করতে হবে (অ্যানালগ্যালি ভিটেবল লুচিংয়ের জন্য), এটি ব্যয়বহুল যদি আপনি এটি অনেক কিছু করেন তবে বার।

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

দুঃখের বিষয়, এটি বিমূর্তির চূড়ান্ত ত্রুটি; আপনি যে বিমূর্ততা চয়ন করেন তা বিবেচনা না করেই, আপনার বিমূর্ততা কেবলমাত্র আপনি যে সমস্যার সমাধান করতে চাইছেন তার প্রসঙ্গেই অর্থবোধ করতে পারে এবং যেমন আপনি কোনও ধরণের সামঞ্জস্যপূর্ণ বিমূর্ততা রাখতে পারবেন না যা অন্তর্নিহিত মতাদর্শগুলির সাথে অসম্পূর্ণ হয়ে উঠবে না কারণ আপনি সেগুলি ঘষতে শুরু করেন as আপনার মতাদর্শের সাথে সামঞ্জস্যপূর্ণ এমন দৃশ্যে এগুলি মোড়ানো ছাড়াই একসাথে এটি জেনে, পাইথনের পদ্ধতির তুলনায় এটি আরও নমনীয়, কারণ এটি আপনার নিজের মোড়ক তৈরি করে বা আপনার নিজস্ব প্রিপ্রোসেসর তৈরির মাধ্যমে এটি আরও "সুন্দর" দেখানোর জন্য আরও বেশি অর্থ প্রদান করা আপনার উপর নির্ভর করে।


0

ভেরিয়েবল my_listএবং "-"উভয় বস্তু। বিশেষত, তারা যথাক্রমে ক্লাসগুলির উদাহরণ listএবং strjoinফাংশন শ্রেণী জন্যে str। সুতরাং, সিনট্যাক্সটি "-".join(my_list)ব্যবহৃত হয় কারণ বস্তুটি একটি ইনপুট হিসাবে "-"নিচ্ছে my_list

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