পাইথন আইডিয়ামটি প্রথম আইটেম বা কোনওটিই ফিরিয়ে দেবে না


272

আমি নিশ্চিত যে এটি করার একটি সহজ উপায় আছে যা আমার কাছে ঘটে না।

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

my_list = get_list()
if len(my_list) > 0: return my_list[0]
return None

আমার কাছে মনে হয় এটি করার জন্য একটি সাধারণ এক-লাইন প্রতিমা থাকা উচিত, তবে আমার জীবনের জন্য আমি এটি ভাবতে পারি না। আছে?

সম্পাদনা:

যে কারণে আমি এখানে এক-লাইন প্রকাশ করতে চাইছি তা হ'ল আমি অবিশ্বাস্যভাবে সংশ্লেষ কোড পছন্দ করি না, তবে কারণ আমাকে অনেকগুলি কোড লিখতে হচ্ছে:

x = get_first_list()
if x:
    # do something with x[0]
    # inevitably forget the [0] part, and have a bug to fix
y = get_second_list()
if y:
    # do something with y[0]
    # inevitably forget the [0] part AGAIN, and have another bug to fix

আমি যা করতে চাই তা অবশ্যই একটি ফাংশন দিয়ে সম্পাদন করা যেতে পারে (এবং সম্ভবত এটি হবে):

def first_item(list_or_none):
    if list_or_none: return list_or_none[0]

x = first_item(get_first_list())
if x:
    # do something with x
y = first_item(get_second_list())
if y:
    # do something with y

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


28
বিটিডব্লিউ, পাইথন ২.6+ তে আপনি ধরে নেওয়ার next(iter(your_list), None)পরিবর্তে ব্যবহার করতে পারেন তা নয় ( এবং সর্বদা অবশ্যই পুনরাবৃত্ত হওয়া উচিত)। first_item(your_list)your_listNoneget_first_list()get_second_list()
jfs

1
আমি মনে করি আপনি বোঝাতে চাইছেন next(iter(your_list))যেহেতু আপনি যদি দ্বিতীয় যুক্তি সরবরাহ করেন তবে iterআপনি এটি বলছেন যে প্রথম যুক্তিটি কলযোগ্য।
রবার্ট রসনি

7
না, Noneএখানে দ্বিতীয় প্যারামিটারটি রয়েছে next(), নেই iter()। খালি যদি next()উত্থাপনের পরিবর্তে দেওয়া হয় তবে এটির দ্বিতীয় প্যারামিটারটি দেয় returns StopIterationyour_list
jfs

@JFSebastian দ্বারা প্রস্তাবিত সমাধান ডুপ্লিকেট প্রশ্নের সঙ্গে বিদ্যমান: stackoverflow.com/a/18533669/144408
shahjapan

উত্তর:


205

পাইথন 2.6+

next(iter(your_list), None)

যদি your_listহতে পারে None:

next(iter(your_list or []), None)

পাইথন 2.4

def get_first(iterable, default=None):
    if iterable:
        for item in iterable:
            return item
    return default

উদাহরণ:

x = get_first(get_first_list())
if x:
    ...
y = get_first(get_second_list())
if y:
    ...

অন্য বিকল্পটি হ'ল উপরের ফাংশনটি ইনলাইন করা:

for x in get_first_list() or []:
    # process x
    break # process at most one item
for y in get_second_list() or []:
    # process y
    break

এড়াতে breakআপনি লিখতে পারেন:

for x in yield_first(get_first_list()):
    x # process x
for y in yield_first(get_second_list()):
    y # process y

কোথায়:

def yield_first(iterable):
    for item in iterable or []:
        yield item
        return

1
এই শেষ বিকল্পটি আমি ঠিক ঠিক যা খুঁজছি তা হ'ল: এটি পরিষ্কার, এটি কাজ করে এবং এর জন্য আমার কোনও নতুন ফাংশন সংজ্ঞায়িত করার প্রয়োজন হয় না। ব্রেকটি কোনওরকমের প্রয়োজন না হলে আমি "ঠিক" বলব, কারণ এটি বাদ দেওয়ার ঝুঁকি তুচ্ছ নয়। তবে এই পদ্ধতির সত্যের আংটি রয়েছে।
রবার্ট রসনি

ওহ, আমি এটি মোটেও পছন্দ করি না। তালিকার কোনও আইটেম যদি মিথ্যা মূল্যায়ন করে তবে সেই মানটি বাতিল করে প্রতিস্থাপন করা হবে। তালিকায় যদি আপনার খালি স্ট্রিং ""থাকে তবে তা বাতিল করে খালি তালিকায় প্রতিস্থাপন করা হবে []। আপনার যদি 0 থাকে তবে প্রতিস্থাপনও করুন []। আপনি যদি Falseসেখানে থাকেন তবে প্রতিস্থাপনও করুন। ইত্যাদি আপনি একটি নির্দিষ্ট ক্ষেত্রে এটি থেকে দূরে সরে যেতে পারেন, তবে এটি বিকাশের একটি খারাপ অভ্যাস।
স্টিভাহ

4
@ স্টেভেহা: bool(lst) আমাদের len(lst) > 0কী কী আইটেমগুলি lstরয়েছে সে সম্পর্কে কিছু না বলে কিনা তা আমাদের জানান , bool([False]) == True;তাই এক্সপ্রেশনটি [False] or []ফিরে আসে [False], [0] or [] এটির জন্য এটিই ফিরে আসে [0]
jfs

@ রবার্টরোসনি: বিবৃতি yield_first()এড়াতে আমি যুক্ত করেছি break
jfs

1
@ থমাস অহলে: উভয়ই সত্য। নন-নন কেসের সমাধান দেওয়ার জন্য আমি উত্তর আপডেট করেছি।
jfs

218

সর্বোত্তম উপায় হ'ল:

a = get_list()
return a[0] if a else None

আপনি এটি এক লাইনেও করতে পারেন, তবে প্রোগ্রামারটির পক্ষে এটি পড়া খুব কঠিন:

return (get_list()[:1] or [None])[0]

উফ। এটি উল্লেখ করা উচিত ছিল এটি একটি পাইথন ২.৪ অ্যাপ।
রবার্ট রসনি

15
@ অ্যাডাম: ভবিষ্যত ব্যবহার করতে পারেnext(iter(your_list), None)
jfs

@ জেএসএবেস্টিয়ান আসলেই next(iter(your_list))যথেষ্ট
ব্র্যাড জনসন

13
@ ব্র্যাডলিঘা জনসন: ভুল এটি Noneওপি যেমন জিজ্ঞাসা করবে ফিরে আসার পরিবর্তে স্টপআইটারেশন উত্থাপন করে। চেষ্টা করুন: next(iter([]))
jfs

72
(get_list() or [None])[0]

এটা কাজ করা উচিত।

বিটিডব্লিউ আমি ভেরিয়েবলটি ব্যবহার করি নি list, কারণ এটি বিল্টিন list()ফাংশনটিকে ওভাররাইট করে ।

সম্পাদনা: আমার এখানে আগে কিছুটা সহজ, তবে ভুল সংস্করণ ছিল।


4
এটি চালাক এবং কার্যকর, তবে আমি মনে করি "ফিফু [0] যদি ফোটো আর কেউ না" ইফোটিনিস অনুসারে রক্ষণাবেক্ষণের জন্য অনুসরণ করা কিছুটা সহজ।
জে

3
প্রশ্নটি একটি লাইন সমাধানের জন্য জিজ্ঞাসা করেছিল, তাই আমি তা বাতিল করে দিয়েছি।
পুনরাবৃত্তি

Get_list () কোনওটি ফেরত না দিলে এই এক্সপ্রেশনগুলির কোনওটিই কাজ করে না; আপনি "TypeError: 'NoNype" অবজেক্টটি আনসস্ক্রিপ্টযোগ্য get বা "TypeError: +: 'NoNype' এবং 'list' এর জন্য অসমর্থিত অপরেন্দ্র প্রকার (গুলি)"
রবার্ট রসনি

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

Get_list () আর কিছু না প্রত্যাবর্তন করে এখনই কাজ করা উচিত কারণ এটি সাবস্ক্রিপশন বা যোগ করা হয় না।
রবার্ট

32

তালিকাটি পুনরাবৃত্তিযোগ্য হওয়ায় সর্বাধিক অজগর আইডিয়োমেটিক উপায় হ'ল একটি পুনরুক্তকারীটিতে পরবর্তী () ব্যবহার করা । ১৩ ই ডিসেম্বর, ২০১১ এ ঠিক কীভাবে @ জেএফএসবেস্টিয়ান মন্তব্যটিতে লিখেছেন।

next(iter(the_list), None)the_listখালি থাকলে এটি কোনওটিই প্রদান করে না। দেখতে পরবর্তী () পাইথন 2.6+

অথবা আপনি যদি নিশ্চিত জানেন যে the_listশূন্য নয়:

iter(the_list).next()দেখতে iterator.next () পাইথন 2.2+


1
এটির সুবিধাটি রয়েছে যে আপনার তালিকাটি কোনও ভেরিয়েবলের মতো আপনার তালিকাটি নির্ধারণ করতে হবে না return l[0] if l else Noneযদি তালিকাটি একটি libcomp ছিল। তালিকাটি আসলে একটি জেনেক্সপ্রেট হওয়ার পরে এটি আরও ভাল হয় কারণ আপনাকে পুরো তালিকাটি এর মতো তৈরি করতে হবে নাnext(iter(x for x in range(10) if x % 2 == 0), None)
রুবেললগুনা

আপনি যদি নিশ্চিতরূপে জানেন যে the_listশূন্য নয়, আপনি লিখবেন the_list[0]
কেয়া 3

12

যদি আপনি নিজেকে একটি তালিকা বোঝার থেকে প্রথম জিনিসটি (বা কিছুই নয়) কেড়ে নেওয়ার চেষ্টা করে দেখতে পান তবে আপনি এটির মতো কোনও জেনারেটরে যেতে পারেন:

next((x for x in blah if cond), None)

প্রো: কাজ করে যদি ব্লাহ সূচকযোগ্য না হয়: এটি অপরিচিত সিনট্যাক্স। যদিও আইপথনে আশেপাশে হ্যাক করা এবং স্টাফ ফিল্টার করার সময় এটি দরকারী।


11

ওপির সমাধানটি প্রায় রয়েছে, আরও পাইথোনিক করার জন্য এখানে কয়েকটি জিনিস রয়েছে।

এক জন্য, তালিকার দৈর্ঘ্য পাওয়ার দরকার নেই। পাইথনের খালি তালিকাগুলি যদি চেক হয় তবে মিথ্যাতে মূল্যায়ন করে। শুধু সহজভাবে বলতে

if list:

অতিরিক্তভাবে, সংরক্ষিত শব্দের সাথে ওভারল্যাপ হওয়া ভেরিয়েবলগুলিকে নির্ধারণ করা খুব খারাপ ধারণা। "তালিকা" পাইথনের একটি সংরক্ষিত শব্দ।

সুতরাং আসুন যে এটি পরিবর্তন করা যাক

some_list = get_list()
if some_list:

একটি সত্যিকারের গুরুত্বপূর্ণ বিষয় যা এখানে প্রচুর সমাধানগুলি মিস করে তা হ'ল সমস্ত পাইথন ফাংশন / পদ্ধতিগুলি ডিফল্টরূপে কিছুই দেয় না । নীচের নীচে চেষ্টা করুন।

def does_nothing():
    pass

foo = does_nothing()
print foo

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

some_list = get_list()
if some_list:
    return list[0]

এবং পরিশেষে, সম্ভবত এটি অন্তর্ভুক্ত ছিল, তবে কেবল স্পষ্ট করে বলা (কারণ সুস্পষ্টর চেয়ে আরও ভাল ভাল ), আপনার ক্রিয়াকলাপটি অন্য ফাংশন থেকে তালিকাটি পাওয়া উচিত নয়; একটি পরামিতি হিসাবে এটি পাস। সুতরাং, চূড়ান্ত ফলাফল হবে

def get_first_item(some_list): 
    if some_list:
        return list[0]

my_list = get_list()
first_item = get_first_item(my_list)

যেমনটি আমি বলেছিলাম, ওপি প্রায় ছিল, এবং মাত্র কয়েকটি ছোঁয় এটির জন্য পাইথন গন্ধটি সন্ধান করছে।


1
পাইথনটিতে 'তালিকা' একটি সংরক্ষিত শব্দ কেন? বা, আরও উল্লেখযোগ্য বিষয়, কোথায় এটি বলে যে 'তালিকা' পাইথনের একটি সংরক্ষণক শব্দ? অথবা, আরও উল্লেখযোগ্যভাবে, আপনি কীভাবে যাচাই করেছেন যে 'তালিকা' অজগরটিতে একটি সংরক্ষিত শব্দ? আমি 'তালিকা' নামের একটি ভেরিয়েবল ঘোষণা করতে পারি তা বিবেচনা করে, এটি স্পষ্টত কোনও সংরক্ষিত শব্দ নয়।
লাসে ভি কার্লসেন

2
পয়েন্ট নেওয়া হয়েছে। পাইথনের সত্যিকার অর্থে সংরক্ষিত শব্দগুলি এখানে পাওয়া যাবে tinyurl.com/424663 তবে, বিল্টিন ফাংশন এবং প্রকারগুলি সংরক্ষিত হিসাবে বিবেচনা করা ভাল ধারণা। তালিকা () আসলে একটি তালিকা তৈরি করে। একই ডিক, রেঞ্জ ইত্যাদির জন্য যায়
গিগেনেস

অস্থায়ী ভেরিয়েবলটি সরিয়ে আমি শেষ দুটি লাইন একত্রিত করব (যতক্ষণ না আপনার আমার আরও_ তালিকা দরকার হয়)। যা পাঠযোগ্যতার উন্নতি করে।
সোভান্তে

আমি উত্তরের দিকে যে উত্তরটি আকর্ষণীয় করেছিলাম তা এটি বেশ।
রবার্ট রসনি

1
get_first_itemএমন একটি defaultপ্যারামিটার গ্রহণ করতে হবে (যেমন dict.get) যা নিজেকে কারও কাছে ডিফল্ট করে না। সুতরাং ফাংশন ইন্টারফেসটি my_listখালি থাকলে কী ঘটে তা স্পষ্টভাবে যোগাযোগ করে ।
jfs

3
for item in get_list():
    return item

এটি সংক্ষিপ্ত এবং সুন্দর।
গিগেনেস

দুঃখজনকভাবে, এটি কাজ করে না; get_list () যদি কিছুই না ফেরায় তবে এটি একটি "TypeError: 'NoNype' অবজেক্টটি পুনরাবৃত্তিযোগ্য নয়" ব্যতিক্রম করে।
রবার্ট রসনি

ঠিক করতে: "get_list () বা []:" আইটেমের জন্য: "
এরআডোক

5
প্রশ্নটি পরিষ্কারভাবে অনুমান করে get_list একটি তালিকা দেয়। লেন এবং গেটাইটেমকে তার ফলাফলের জন্য ডাকা হয়।
এ Coady

2

খোলামেলা কথা বললে, আমি মনে করি না যে এর থেকে ভাল প্রতিবাদ আছে: আপনার স্পষ্ট এবং সংবেদনশীল - কোনও "ভাল" এর প্রয়োজন নেই। হয়তো, কিন্তু এই সত্যিই স্বাদ ব্যাপার, আপনি পরিবর্তন পারে if len(list) > 0:সঙ্গে if list:একটি খালি তালিকা সবসময় মিথ্যাতে মূল্যায়ন করবে -।

সম্পর্কিত নোটে, পাইথন পার্ল নয় (কোনও পাং উদ্দেশ্য নয়!), আপনাকে সর্বোত্তমতম কোডটি পেতে হবে না।
আসলে, পাইথনে আমি সবচেয়ে খারাপ কোডটি দেখেছি, এটিও খুব দুর্দান্ত :-) এবং সম্পূর্ণ অনিবার্য ছিল।

যাইহোক, আমি যে সমাধানগুলি এখানে দেখেছি সেগুলির বেশিরভাগ বিবেচনা বিবেচনা করে না যখন তালিকা [0] মিথ্যা (যেমন খালি স্ট্রিং, বা শূন্য) এর মূল্যায়ন করে - এই ক্ষেত্রে, তারা সকলেই কোনও কিছুই দেয় না এবং সঠিক উপাদানটি নয়।


পাইথনে এটি লেখার if lst:চেয়ে ভাল স্টাইল হিসাবে বিবেচনা করা হয় if len(lst) > 0:। এছাড়াও, পাইথন কীওয়ার্ডগুলি ভেরিয়েবলের নাম হিসাবে ব্যবহার করবেন না; কান্না শেষ হয়। এটা তোলে সাধারণ ব্যবহার করতে Lবা lstকিছু তালিকার জন্য পরিবর্তনশীল নামের। আমি নিশ্চিত এই ক্ষেত্রে আপনি আসলে listএকটি ভেরিয়েবল নাম হিসাবে ব্যবহার করার পরামর্শ দিচ্ছেন না , আপনি কেবল "কিছু তালিকা" বোঝাতে চাইছেন । এবং, "যখন lst [0] মিথ্যাতে মূল্যায়ন করে" এর জন্য +1।
স্টিভাহ

হ্যাঁ, আমি আরও স্পষ্টতার জন্য কেবল ওপির একই ধরণের নাম বজায় রেখেছিলাম। তবে আপনি অবশ্যই সত্য বলেছেন: পাইথনের কীওয়ার্ডগুলিকে ওভাররাইড না করার জন্য কিছু যত্ন নেওয়া উচিত।
লুঠ করুন

2

পাইথন আইডিয়ম প্রথম আইটেম ফিরে আসে না কেউ?

সর্বাধিক পাইথোনিক পদ্ধতির মধ্যে সর্বাধিক উত্সাহিত উত্তরটি প্রদর্শিত হয়েছিল এবং আমি যখন প্রশ্নটি পড়ি তখন এটি আমার মনে প্রথম আসে। এটি কীভাবে ব্যবহার করবেন তা এখানে রয়েছে, যদি সম্ভবত খালি তালিকা কোনও ফাংশনে প্রবেশ করা হয়:

def get_first(l): 
    return l[0] if l else None

এবং যদি কোনও get_listফাংশন থেকে তালিকাটি ফিরে আসে :

l = get_list()
return l[0] if l else None

অন্যান্য উপায় ব্যাখ্যা সহ এখানে এটি করার জন্য প্রদর্শিত হয়েছিল

for

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

for item in get_list():
    return item

এটি অনুমান করে এখানে ফাংশনটি শেষ হবে, Noneযদি get_listখালি তালিকা ফেরত দেয় তবে সুস্পষ্টভাবে ফিরে আসবে । নীচের স্পষ্ট কোডটি হুবহু:

for item in get_list():
    return item
return None

if some_list

নিম্নলিখিতটিও প্রস্তাব করা হয়েছিল (আমি ভুল ভেরিয়েবলের নাম সংশোধন করেছি) যা অন্তর্নিহিত ব্যবহার করে None। এটি উপরেরটির চেয়ে পছন্দনীয় হবে কারণ এটি পুনরুক্তির পরিবর্তে লজিকাল চেক ব্যবহার করে যা ঘটতে পারে না। কী হচ্ছে তা অবিলম্বে বোঝা সহজ হওয়া উচিত। তবে আমরা যদি পঠনযোগ্যতা এবং রক্ষণাবেক্ষণের জন্য লিখছি তবে আমাদের return Noneশেষেও স্পষ্ট যুক্ত করা উচিত :

some_list = get_list()
if some_list:
    return some_list[0]

টুকরো টুকরো or [None]করে জিরোথ সূচক নির্বাচন করুন

এইটিও সর্বাধিক ভোটপ্রাপ্ত উত্তরে:

return (get_list()[:1] or [None])[0]

স্লাইস অপ্রয়োজনীয়, এবং মেমরিতে অতিরিক্ত একটি-আইটেমের তালিকা তৈরি করে। নিম্নলিখিত আরও পারফরম্যান্স করা উচিত। ব্যাখ্যা করার জন্য, orপ্রথমটি Falseবুলিয়ান প্রসঙ্গে থাকলে দ্বিতীয় উপাদানটি প্রদান করে, সুতরাং যদি get_listখালি তালিকাটি ফিরে আসে, তবে প্রথম বন্ধনীতে থাকা এক্সপ্রেশনটি 'কিছুই নয়' দিয়ে একটি তালিকা ফিরিয়ে দেবে, যা 0সূচক দ্বারা অ্যাক্সেস করা হবে :

return (get_list() or [None])[0]

পরেরটি এটি ব্যবহার করে এবং প্রথম আইটেমটি ফিরিয়ে দেয় যদি প্রথমটি Trueবুলিয়ান প্রসঙ্গে থাকে এবং যেহেতু এটি আমার_লিস্টকে দু'বার উল্লেখ করেছে, এটি ত্রিশটি প্রকাশের চেয়ে ভাল নয় (এবং প্রযুক্তিগতভাবে একটি-লাইনার নয়):

my_list = get_list() 
return (my_list and my_list[0]) or None

next

তারপরে আমাদের কাছে বিল্টিন nextএবং এর নিম্নলিখিত চালাক ব্যবহার রয়েছেiter

return next(iter(get_list()), None)

ব্যাখ্যা করতে, iterএকটি .nextপদ্ধতি সহ একটি পুনরাবৃত্তি প্রদান করে । ( .__next__পাইথন ৩. এ) তারপরে বিল্টিন nextসেই .nextপদ্ধতিটি কল করে এবং যদি পুনরুক্তিকারী ক্লান্ত হয়ে যায় তবে আমরা যে ডিফল্টটি দিই তা ফিরিয়ে দেয় None

অপ্রয়োজনীয় ত্রৈমাসিক অভিব্যক্তি ( a if b else c) এবং চক্কর ফিরে

নীচে প্রস্তাব করা হয়েছিল, তবে বিপরীতটিই পছন্দনীয় হবে কারণ যুক্তিটি সাধারণত negativeণাত্মক পরিবর্তে ইতিবাচক ক্ষেত্রে আরও ভাল বোঝা যায়। যেহেতু get_listদু'বার বলা হয়, যদি না ফলাফলটি কোনওভাবে স্মরণ করা হয়, তবে এটি খারাপভাবে সম্পাদন করবে:

return None if not get_list() else get_list()[0]

ভাল বিপরীত:

return get_list()[0] if get_list() else None

আরও ভাল, একটি স্থানীয় ভেরিয়েবল ব্যবহার করুন যাতে get_listকেবল একবারে ডাকা হয় এবং আপনি প্রথমে আলোচিত পাইথোনিক সমাধানটি নিয়ে আলোচনা করেছেন:

l = get_list()
return l[0] if l else None

2

প্রজ্ঞাপন সম্পর্কিত , একটি itertools রেসিপি বলা হয় nth

ইটারটুল রেসিপি থেকে:

def nth(iterable, n, default=None):
    "Returns the nth item or a default value"
    return next(islice(iterable, n, None), default)

যদি আপনি ওয়ান-লাইনার চান, আপনার জন্য এই রেসিপিটি কার্যকর করে এমন একটি লাইব্রেরি ইনস্টল করার বিষয়টি বিবেচনা করুন, যেমন more_itertools:

import more_itertools as mit

mit.nth([3, 2, 1], 0)
# 3

mit.nth([], 0)                                             # default is `None`
# None

আরেকটি টুল শুধুমাত্র প্রথম আইটেম নামক ফেরৎ যে পাওয়া যায় more_itertools.first

mit.first([3, 2, 1])
# 3

mit.first([], default=None)
# None

এই তালিকাগুলি কেবল তালিকার জন্য নয়, কোনও পুনরাবৃত্তির জন্য সাধারণভাবে স্কেল করে।



1

কৌতূহলের বাইরে, আমি দুটি সমাধানের জন্য সময় কাটিয়েছি। লুপের জন্য অকালে শেষ করার জন্য রিটার্ন স্টেটমেন্টটি যে সমাধানটি ব্যবহার করে তা পাইথন ২.২.১ সহ আমার মেশিনে কিছুটা বেশি ব্যয়বহুল, আমি সন্দেহ করি যে এটি পুনরাবৃত্তিযোগ্য স্থাপনের সাথে করা উচিত।

import random
import timeit

def index_first_item(some_list):
    if some_list:
        return some_list[0]


def return_first_item(some_list):
    for item in some_list:
        return item


empty_lists = []
for i in range(10000):
    empty_lists.append([])

assert empty_lists[0] is not empty_lists[1]

full_lists = []
for i in range(10000):
    full_lists.append(list([random.random() for i in range(10)]))

mixed_lists = empty_lists[:50000] + full_lists[:50000]
random.shuffle(mixed_lists)

if __name__ == '__main__':
    ENV = 'import firstitem'
    test_data = ('empty_lists', 'full_lists', 'mixed_lists')
    funcs = ('index_first_item', 'return_first_item')
    for data in test_data:
        print "%s:" % data
        for func in funcs:
            t = timeit.Timer('firstitem.%s(firstitem.%s)' % (
                func, data), ENV)
            times = t.repeat()
            avg_time = sum(times) / len(times)
            print "  %s:" % func
            for time in times:
                print "    %f seconds" % time
            print "    %f seconds avg." % avg_time

এই সময়গুলি আমি পেয়েছি:

empty_lists:
  index_first_item:
    0.748353 সেকেন্ড
    0.741086 সেকেন্ড
    0.741191 সেকেন্ড
    0.743543 সেকেন্ড গড়।
  return_first_item:
    0.785511 সেকেন্ড
    0.822178 সেকেন্ড
    0.782846 সেকেন্ড
    0.796845 সেকেন্ড গড়।
full_lists:
  index_first_item:
    0.762618 সেকেন্ড
    0.788040 সেকেন্ড
    0.786849 সেকেন্ড
    0.779169 সেকেন্ড গড়।
  return_first_item:
    0.802735 সেকেন্ড
    0.878706 সেকেন্ড
    0.808781 সেকেন্ড
    0.830074 সেকেন্ড গড়।
mixed_lists:
  index_first_item:
    0.791129 সেকেন্ড
    0.743526 সেকেন্ড
    0.744441 সেকেন্ড
    0.759699 সেকেন্ড গড়।
  return_first_item:
    0.784801 সেকেন্ড
    0.785146 সেকেন্ড
    0.840193 সেকেন্ড
    0.803380 সেকেন্ড গড়।

0
try:
    return a[0]
except IndexError:
    return None

1
ব্যতিক্রমগুলি সাধারণত প্রবাহ নিয়ন্ত্রণের জন্য ব্যবহৃত হয় না।
ম্যাট গ্রিন

আমি মনে করি না এই কোডটি দীর্ঘতর করা এবং এর সাথে ব্যতিক্রম-হ্যান্ডলিং যুক্ত করা ঠিক হ'ল আইডিয়ম যা আমি খুঁজছিলাম is
রবার্ট রসনি 21

3
তবে এটি একটি সাধারণ পাইথন আইডিয়ম! কর্মক্ষমতা কারণে, আপনি এটি ব্যবহার নাও করতে পারেন; আপনি আরও ভাল পারফরম্যান্স পাবেন if len(a) > 0:তবে এটিকে ভাল স্টাইল হিসাবে বিবেচনা করা হয়। এটি সমস্যাটি কতটা ভালভাবে প্রকাশ করে তা নোট করুন: "একটি তালিকার মাথাটি বের করার চেষ্টা করুন এবং যদি এটি কার্যকর না হয় তবে ফিরে যান None"। গুগল "ইএএফপি" এর জন্য অনুসন্ধান করুন বা এখানে দেখুন: পাইথন.ন.
ood

@ স্টেভেহা এটি আপনার ডেটার উপর নির্ভর করে। যদি লেন (ক) সাধারণত> 0 হয় এবং লেন (ক) <1 বিরল অবস্থা হয় তবে ব্যতিক্রম ধরা আসলে আরও পারফরম্যান্ট হবে।
লিমস্কোডার

@ লিমস্কোডার, আমি আপনার সাথে একমত আপনি কখন পারফরম্যান্সের কারণে এটি ব্যবহার করবেন না সে সম্পর্কে আমি কেবল বিশদে প্রবেশ করি নি; আমি বলিনি যে আপনি এটি কখনও ব্যবহার করবেন না।
স্টিভেহা

0
def head(iterable):
    try:
        return iter(iterable).next()
    except StopIteration:
        return None

print head(xrange(42, 1000)  # 42
print head([])               # None

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

lists = [
    ["first", "list"],
    ["second", "list"],
    ["third", "list"]
]

def do_something(element):
    if not element:
        return
    else:
        # do something
        pass

for li in lists:
    do_something(head(li))

(যখনই সম্ভব পুনরাবৃত্তি এড়ানো)


0

এটি সম্পর্কে:

(my_list and my_list[0]) or None

দ্রষ্টব্য: বস্তুর তালিকাগুলির তালিকার জন্য এটি ভাল কাজ করা উচিত তবে নীচের মন্তব্যে সংখ্যা বা স্ট্রিং তালিকার ক্ষেত্রে এটি ভুল উত্তর দিতে পারে।


কি সম্পর্কে ([0,1] and 0) or None!
কেনলি

এটি একটি ভাল পয়েন্ট ... বর্তমান আকারে নম্বর সংগ্রহের সাথে ব্যবহার করা অনিরাপদ :(
VitalyB

একই জিনিস (['','A'] and '') or None
কেনলি

যদি my_list[0]হিসাবে মূল্যায়ন করা হয় False, ফলাফল হওয়া উচিত None
কেনলি

2
my_list[0] if len(my_list) else None
নিকোলাস হ্যামিল্টন

0

এটি কতটা অজগর তা নিশ্চিত নয় তবে লাইব্রেরিতে প্রথম ফাংশন না হওয়া পর্যন্ত আমি এটি উত্সে অন্তর্ভুক্ত করছি:

first = lambda l, default=None: next(iter(l or []), default)

এটি কেবলমাত্র একটি লাইন (কালো অনুসারে) এবং নির্ভরতা এড়ায়।



-1

সম্ভবত দ্রুততম সমাধান নয়, তবে কেউই এই বিকল্পটির উল্লেখ করেননি:

dict(enumerate(get_list())).get(0)

যদি get_list()ফিরে আসতে পারেন Noneআপনি ব্যবহার করতে পারেন:

dict(enumerate(get_list() or [])).get(0)

সুবিধাদি:

-এক লাইন

- আপনি শুধু get_list()একবার ফোন করুন

-সহজে বোধগম্য


-1

আমার ব্যবহারের ক্ষেত্রটি কেবলমাত্র স্থানীয় ভেরিয়েবলের মান নির্ধারণের জন্য।

ব্যক্তিগতভাবে আমি চেষ্টা করেছি এবং পড়ার জন্য স্টাইল ক্লিনার বাদে

items = [10, 20]
try: first_item = items[0]
except IndexError: first_item = None
print first_item

একটি তালিকা কাটা চেয়ে।

items = [10, 20]
first_item = (items[:1] or [None, ])[0]
print first_item

-1

বেশ কিছু লোক এ জাতীয় কিছু করার পরামর্শ দিয়েছেন:

list = get_list()
return list and list[0] or None

এটি অনেক ক্ষেত্রে কাজ করে তবে এটি কেবল তখনই কাজ করবে যদি তালিকা [0] 0, ফলস বা খালি স্ট্রিংয়ের সমান না হয়। যদি [0] টি 0, ভুয়া বা একটি খালি স্ট্রিং হয় তবে পদ্ধতিটি ভুলভাবে কোনওটিই ফিরিয়ে দেবে না।

আমি এই কোডটি নিজের কোডটিতে অনেক বার তৈরি করেছি!


3
এটি একা একা উত্তরের পরিবর্তে ত্রুটিযুক্ত উত্তর (গুলি) এর অধীনে একটি মন্তব্য হওয়া উচিত।
আইজে কেনেডি

-2

আপনি এক্সট্র্যাক্ট পদ্ধতি ব্যবহার করতে পারেন । অন্য কথায় কোনও কোডে সেই কোডটি বের করুন যা আপনি কল করতে চান।

আমি এটি আরও সংকোচনের চেষ্টা করবো না, এক লাইনারগুলি ভার্বোজ সংস্করণের চেয়ে পড়া আরও কঠিন বলে মনে হয়। এবং যদি আপনি এক্সট্র্যাক্ট পদ্ধতি ব্যবহার করেন তবে এটি একটি লাইনার;)



-3

সি-স্টাইলের টার্নারি অপারেটরগুলির সমকক্ষ অজগর নয়

cond and true_expr or false_expr

অর্থাত।

list = get_list()
return list and list[0] or None

যদি একটি [0] নম্বর 0 বা খালি স্ট্রিং (বা অন্য যে কোনও কিছুকে মিথ্যা হিসাবে মূল্যায়ন করে) হয়, তবে এটি [0] আসলে কী তার পরিবর্তে কোনও কিছুই প্রদান করবে না।
অ্যাডাম রোজেনফিল্ড
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.