পাইথনের তালিকার জন্য কেন "সমতল" ফাংশন নেই?


39

এরলং এবং রুবি উভয়ই অ্যারের সমতলকরণের জন্য ফাংশন নিয়ে আসে। এটি কোনও ভাষায় যুক্ত করার মতো সহজ এবং দরকারী সরঞ্জামের মতো বলে মনে হচ্ছে। কেউ এটি করতে পারে:

>>> mess = [[1, [2]], 3, [[[4, 5]], 6]]
>>> mess.flatten()
[1, 2, 3, 4, 5, 6]

অথবা এমনকি:

>>> import itertools
>>> mess = [[1, [2]], 3, [[[4, 5]], 6]]
>>> list(itertools.flatten(mess))
[1, 2, 3, 4, 5, 6]

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

আমি এটিকে নিরর্থকভাবে গুগল করেছি, তাই আমি এখানে জিজ্ঞাসা করছি; পাইথন 3 এর মতো পরিপক্ক ভাষা, যেখানে এক লাখ বিভিন্ন ব্যাটারি অন্তর্ভুক্ত রয়েছে, এটি কী সমতল করার সহজ পদ্ধতি সরবরাহ করে না? এই জাতীয় অনুষ্ঠানটি অন্তর্ভুক্ত করার ধারণাটি কি কোনও পর্যায়ে আলোচনা ও প্রত্যাখ্যাত হয়েছে?


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

4
"আমি বোঝাতে চাইছি, আপনি যদি নিজের কোডটিতে এমন কোনও ত্রুটি প্রবর্তন করেন যা অজান্তেই আপনার ডেটার কাঠামো পরিবর্তন করে flat ;-)
জর্জিও


2
@BryanOakley পাশাপাশি পূর্বে মন্তব্য দেখুন (যদিও মাল্টি লেভেল তালিকা নয়, সাধারণভাবে সমরূপতার হয় একই)
Izkata

3
এটি ম্যাথামাইকাতে অন্তর্নির্মিত এবং আমি এটি ব্যাপকভাবে ব্যবহার করি।
আলেকজান্ডারসন

উত্তর:


34

flattenস্ট্যান্ডার্ড লাইব্রেরিতে কোনও ফাংশনের জন্য প্রস্তাবগুলি পাইথন-ডেভ এবং পাইথন-আইডিয়াগুলি মেলিং তালিকাগুলিতে সময়ে সময়ে উপস্থিত হয় । পাইথন বিকাশকারীরা সাধারণত নিম্নলিখিত পয়েন্টগুলির সাথে প্রতিক্রিয়া জানান:

  1. একটি এক-স্তরের সমতল (পুনরাবৃত্তির পুনরাবৃত্তিকে একক পুনরায় আবৃত্তিতে পরিণত করা) একটি তুচ্ছ এক-লাইন প্রকাশ (x for y in z for x in y)এবং যে কোনও ক্ষেত্রে ইতিমধ্যে নামের অধীনে স্ট্যান্ডার্ড লাইব্রেরিতে রয়েছে itertools.chain.from_iterable

  2. সাধারণ-উদ্দেশ্যে বহু-স্তরের সমতল জন্য ব্যবহারের ক্ষেত্রে কী কী? স্ট্যান্ডার্ড লাইব্রেরিতে ফাংশন যুক্ত করার জন্য এগুলি কি আসলেই যথেষ্ট বাধ্য?

  3. কীভাবে একটি সাধারণ-উদ্দেশ্য বহুমুখী সমতল স্থির করবে এবং কখন একা ছেড়ে যাবে? আপনি ভাবতে পারেন যে "পুনরাবৃত্ত ইন্টারফেস সমর্থন করে এমন কোনও কিছুকে সমতল করুন" এর মতো একটি নিয়ম কাজ করবে, তবে এটি একটি অসীম লুপের দিকে নিয়ে যাবে flatten('a')

উদাহরণস্বরূপ দেখুন রেমন্ড হেট্টিংগার :

এটি comp.lang.python এ অ্যাড নোসামের বিষয়ে আলোচনা করা হয়েছে । ইতিমধ্যে তুচ্ছ সমাধান নেই এমন বৈধ ব্যবহারের ক্ষেত্রে সন্ধানের চেয়ে লোকেদের নিজের সংস্করণগুলি আরও বেশি সমতল করে লেখা উপভোগ করা যায় বলে মনে হয়।

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


কেবল স্পষ্ট করে বলতে গেলে, এর অর্থ এক-স্তরের flattenফাংশন হিসাবে সংজ্ঞায়িত করা যায় lambda z: [x for y in z for x in y]
ক্রিস্টোফার মার্টিন

1
"একটি সাধারণ উদ্দেশ্য সম্পর্কিত ফ্ল্যাটারকে কিছুটা বলতে হবে যা কী পারমাণবিক এবং কী আরও উপ-বিভাজন হতে পারে তা বলার জন্য।": এটি এমন সমস্যার মতো মনে হয় যা ওওপি ব্যবহার করে সমাধান করা যায়: প্রতিটি বস্তুর একটি flattenপদ্ধতি থাকতে পারে । এই পদ্ধতির বাস্তবায়নের জন্য flattenপুনরুক্তভাবে তার উপ-কম্পোনেন্টকে কল করা উচিত , যদি বস্তুটি কোনও যৌগিক হয়। দুর্ভাগ্যক্রমে, এএফএআইকি প্রতিটি মান পাইথনের কোনও বস্তু নয়। রুবিতে যদিও এটি কাজ করা উচিত।
জর্জিও

1
ইতিমধ্যে "ইন ইন ইন" চালিয়ে যাওয়ার চেয়ে এক স্তরের সমতল জন্য সমতল সহায়ক ইতিমধ্যে যথেষ্ট পরিমাণে আইএমও। সহজেই পঠনযোগ্য
dtc

2
@ জর্জিও পাইথন এ জাতীয় পদ্ধতি থেকে দূরে সরে যায়। প্রোটোকলগুলি অগ্রাধিকার দেওয়া হয় এবং আমি দেখতে পাই যে ওও ডিজাইনের তুলনায় তারা কাজ করতে বেশ স্বাচ্ছন্দ্যময় যেহেতু আপনার প্রায়শই খুব বেশি প্রয়োগ করার প্রয়োজন হয় না।
jpmc26

8

এটি এ জাতীয় পদ্ধতিতে আসে তবে এটি এটিকে ফ্ল্যাট বলে না। একে বলা হয় " চেইন "। এটি একটি পুনরাবৃত্তিকে ফেরত দেয় যা আপনাকে আবার তালিকাতে ফেরাতে তালিকার () ফাংশনটি ব্যবহার করতে হবে। আপনি যদি * ব্যবহার করতে না চান তবে আপনি দ্বিতীয় "from_iterator" সংস্করণটি ব্যবহার করতে পারেন। পাইথন 3 এ এটি একই কাজ করে It তালিকার ইনপুট তালিকার তালিকা না থাকলে এটি ব্যর্থ হবে।

[[1], [2, 3], [3, 4, 5]] #yes
[1, 2, [5, 6]] #no

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

নির্লজ্জের অ্যারে এবং লাইব্রেরির সমতলতার মাধ্যমে স্বেচ্ছাসেবী গভীরতা অর্জন করা যায়।


chain.from_iteratorফাংশন, যেমনটা আপনি বলছেন, শুধুমাত্র দ্বি-মাত্রিক তালিকা চেপ্টা ব্যবহার করা যেতে পারে। একটি actualy চেপ্টা ফাংশন, যা গ্রহণ করে কোনো নেস্টেড তালিকা এবং আয় এক মাত্রিক তালিকা পরিমাণে, এখনও মামলা প্রচুর (অন্তত আমার মতে) এ ব্যাপক দরকারী হবে
Hubro

2
@ হুব্রো: "অনেক ক্ষেত্রে" - আপনি ছয়জনের নাম রাখতে পারবেন?
গ্যারেথ রিস

1
@ গ্যারেথরিস: আমি এখানে কয়েকটি উদাহরণ দিয়েছি: প্রোগ্রামার্স.স্ট্যাকেক্সেঞ্জিং
হুব্রো

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

এটি কি পুনরুক্তিকারী বা জেনারেটর ফেরত দেয়?
jpmc26

-1

... সম্ভবত কারণ নিজের লেখার পক্ষে এতটা অসুবিধা নয়

def flatten(l): return flatten(l[0]) + (flatten(l[1:]) if len(l) > 1 else []) if type(l) is list else [l]

... এবং তারপরে আপনি যা চান তা সমতল করুন :)

>>> flatten([1,[2,3],4])
[1, 2, 3, 4]
>>> flatten([1, [2, 3], 4, [5, [6, {'name': 'some_name', 'age':30}, 7]], [8, 9, [10, [11, [12, [13, {'some', 'set'}, 14, [15, 'some_string'], 16], 17, 18], 19], 20], 21, 22, [23, 24], 25], 26, 27, 28, 29, 30])
[1, 2, 3, 4, 5, 6, {'age': 30, 'name': 'some_name'}, 7, 8, 9, 10, 11, 12, 13, set(['set', 'some']), 14, 15, 'some_string', 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
>>> 

8
প্রশ্নকর্তা এটি সম্পর্কে অবগত: "পাইথন-এ, স্ক্র্যাচ থেকে অ্যারে সমতল করার জন্য একটি ফাংশন লেখার সমস্যায় পড়তে হয়"। এমনকি এটি জিজ্ঞাসা করা প্রশ্নটি সমাধান করার চেষ্টাও করে না, "এটি আমার কাছে নির্বোধ বলে মনে হচ্ছে, চ্যাপ্টা অ্যারে করা এমন একটি সাধারণ কাজ two এটি দুটি অ্যারে যুক্ত করার জন্য একটি কাস্টম ফাংশন লেখার মতো" "
gnat

1
বিষয় ছাড়াই ... তবে দুর্দান্ত দুর্দান্ত :-) !!
SEF

এই উত্তরটি ওপিকে বলার মতো যা তিনি কোনও ভাল বিকাশকারী নন কারণ তিনি নিজেই কীভাবে ফাংশনটি কোডিং করবেন তা তিনি জানতেন না। আমি আপনাকে আপনার উত্তরের সূচনাটি পরিবর্তন করার পরামর্শ দিচ্ছি কারণ যারা প্রশ্নটিতে হোঁচট খাচ্ছেন তাদের পক্ষে এটি কার্যকর কোড, এমনকি যদি বিষয়টি অফ-টপিক হয়
ফেডেরিকো বোনেলি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.