মাথা এবং লেজ এক লাইনে


94

প্রথম উপাদানটিতে একটি তালিকা এবং একটি একক আদেশে "লেজ" আনপ্যাক করার কোনও অজগর উপায় আছে?

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

>> head, tail = **some_magic applied to** [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
>> head
1
>>> tail
[1, 2, 3, 5, 8, 13, 21, 34, 55]

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

উত্তর:


198

পাইথন ৩.x এর অধীনে, আপনি এটিকে সুন্দরভাবে করতে পারেন:

>>> head, *tail = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
>>> head
1
>>> tail
[1, 2, 3, 5, 8, 13, 21, 34, 55]

3.x এ একটি নতুন বৈশিষ্ট্য হ'ল *অপারেটিংটি আনপ্যাকিংয়ে ব্যবহার করা , কোনও অতিরিক্ত মান বোঝানো। এটি পিইপি 3132- এ বর্ণনা করা হয়েছে - এক্সটেন্ডেড আইটেবল আনপ্যাকিং । এটি কেবল সিকোয়েন্সগুলি নয়, কোনও পুনরাবৃত্তির উপর কাজ করার সুবিধাও রয়েছে।

এটি সত্যই পঠনযোগ্য।

পিইপিতে বর্ণিত হিসাবে, আপনি যদি ২.x এর অধীনে (সম্ভাব্য কোনও অস্থায়ী তালিকা তৈরি না করে) সমতুল্য করতে চান তবে আপনাকে এটি করতে হবে:

it = iter(iterable)
head, tail = next(it), list(it)

মন্তব্যে উল্লিখিত হিসাবে, এটি headএকটি ব্যতিক্রম ছোঁড়ার পরিবর্তে ডিফল্ট মান পাওয়ার একটি সুযোগও সরবরাহ করে । আপনি যদি এই আচরণটি চান, next()একটি ডিফল্ট মান সহ একটি alচ্ছিক দ্বিতীয় যুক্তি গ্রহণ করে, তাই যদি কোনও প্রধান উপাদান না থাকে তবে next(it, None)আপনাকে দেবে None

স্বাভাবিকভাবেই, আপনি যদি একটি তালিকায় কাজ করছেন তবে 3.x বাক্য বিন্যাস ছাড়াই সবচেয়ে সহজ উপায় হ'ল:

head, tail = seq[0], seq[1:]

4
দুঃখিত, আমি লেজটি অপ্রয়োজনীয়ভাবে ব্যবহার করেছি। আমি উদাহরণে যা বলছি তার অর্থ, এটি প্রথম উপাদান ছাড়াই
গিয়াকোমো

4
@ নিকোলেফমিনিহ এগুলি উভয়ই সমান - তারা উভয়ই প্রধান উপাদান নিয়ে যায় এবং লেজের উপাদানযুক্ত একটি নতুন তালিকা তৈরি করে। জটিলতায় কোনও পার্থক্য নেই। অন্য শ্রেণীর অলসভাবে লেজ অপারেশন করতে __getitem__/ প্রয়োগ করতে পারে __setitem__, তবে অন্তর্নির্মিত তালিকাটি তা করে না।
গ্যারেথ লেটি

4
এটি 1M বার করে 800 টি উপাদানের তালিকায়, আমি মাথার জন্য 2.8 এস, * লেজ = সিক সমাধান এবং মাথা, লেজ = সিক [0], সিক [1:] সমাধানের জন্য কেবল 1.8 এস। কাটা তালিকা জন্য এখনও দ্রুত।
ক্যাবু

4
@ সিএমসিডিগ্রাগনকাই নং, পাইথনের প্রধান তালিকা শ্রেণি একটি অ্যারে তালিকা। এটি ও (এন) হবে কারণ এটিতে একটি নতুন তালিকায় লেজটি অনুলিপি করা (একটি ও (1) মাথার সাথে পেতে) জড়িত।
গ্যারেথ লেটি

4
এই সুন্দর বাক্য python 3.x
গঠনটি


9

ও (1) head,tailঅপারেশন জটিলতার জন্য আপনার dequeতবে ব্যবহার করা উচিত ।

নিম্নলিখিত উপায়:

from collections import deque
l = deque([1,2,3,4,5,6,7,8,9])
head, tail = l.popleft(), l

তালিকার সমস্ত উপাদানগুলির মাধ্যমে পুনরাবৃত্তি করতে হবে এটি দরকারী It's উদাহরণস্বরূপ নিষ্প্রভ মার্জ 2 পার্টিশন মার্জ সাজানোর মধ্যে।


এটি দেখে মনে হচ্ছে deque (list_instance) এর O (N) জটিলতা রয়েছে। আমি কি ভূল?
Конин Конин

4
@।, আপনি ডেকিং নির্মাণ সম্পর্কে ঠিক বলেছেন। তবে আপনি যদি একাধিকবার প্রথম উপাদানটি অ্যাক্সেস করতে চান তবে তা head, tail = l.popleft(), lহ'ল ~ O (1)। head, tail = seq[0], seq[1:]ও (এন) হয়।
নিকোলে ফমিনিহ

দেখে মনে হচ্ছে আপনি ঠিক কি করতে পারেন head = l.popleft()এবং tailঠিক উপনাম হল l। যদি lপরিবর্তনগুলিও tailপরিবর্তন হয়।
কন সাইক

2

পাইথন 2, ল্যাম্বডা ব্যবহার করে

>>> head, tail = (lambda lst: (lst[0], lst[1:]))([1, 1, 2, 3, 5, 8, 13, 21, 34, 55])
>>> head
1
>>> tail
[1, 2, 3, 5, 8, 13, 21, 34, 55]

4
পৃথিবীতে কেন আপনি ন্যায়বিচারের পরিবর্তে এটি করবেন head, tail = lst[0], lst[1:]? যদি ওপি এর অর্থ আক্ষরিক ব্যবহার হয় তবে সে নিজেই মাথা এবং লেজ ভাগ করে দিতে পারেhead, tail = 1, [1, 2, 3, 5, 8, 13, 21, 34, 55]
ফিলিপ পিনা

4
(1) অপের প্রশ্ন ছিল এটি একটি লাইনে করা সম্ভব ( lst = ...পূর্ববর্তী লাইনে তাই না )। (২) না করার ফলে head, tail = lst[0], lst[1:]কোডটি পার্শ্ব-প্রতিক্রিয়াতে খোলে (বিবেচনা করুন head, tail = get_list()[0], get_list()[1:]), এবং অপের রূপের চেয়ে আলাদা head, tail = **some_magic applied to** [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
ববিআইসনটমাইনেম

বলা হচ্ছে, আমি স্বীকার করি যে এটি মাথা / লেজ পাওয়ার জন্য একটি খারাপ অবলম্বন উপায়। তবে আমি ভেবেছিলাম এটি অপের নির্দিষ্ট প্রশ্নের জন্য পাইথন 2 এর সেরা উত্তর।
ববিআইসনটমাইনেম

1

@ গ্যারেথল্যাটি থেকে পাইথন 2 সমাধানের উপর ভিত্তি করে, পাইথন 2 তে অন্তর্বর্তী ভেরিয়েবলগুলি ছাড়াই একটি একক লাইন সমতুল্য হওয়ার উপায় নীচে।

t=iter([1, 1, 2, 3, 5, 8, 13, 21, 34, 55]);h,t = [(h,list(t)) for h in t][0]

যদি আপনার এটির ব্যতিক্রম-প্রমাণ (যেমন খালি তালিকার পক্ষে সমর্থন করা) দরকার হয় তবে যুক্ত করুন:

t=iter([]);h,t = ([(h,list(t)) for h in t]+[(None,[])])[0]

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

h,t = ([(h,list(t)) for t in [iter([1,2,3,4])] for h in t]+[(None,[])])[0]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.