एक पायथन सूची या यदि उपलब्ध न हो तो डिफ़ॉल्ट का nth तत्व कैसे प्राप्त करें


144

मैं dictionary.get(key, default)सूचियों के लिए अजगर के समकक्ष देख रहा हूं । अगर सूची उपलब्ध नहीं है या डिफ़ॉल्ट मूल्य उपलब्ध नहीं है तो क्या कोई एक लाइनर मुहावरा है?

उदाहरण के लिए, एक सूची दी गई myList मैं प्राप्त करना चाहूंगा myList[0], या 5 यदि myListकोई खाली सूची है।

धन्यवाद।

जवाबों:


124
l[index] if index < len(l) else default

नकारात्मक सूचकांकों का समर्थन करने के लिए हम उपयोग कर सकते हैं:

l[index] if -len(l) <= index < len(l) else default

3
काम नहीं करता है अगर आपकी सूची में नाम नहीं है, हालांकि - उदाहरण के लिए, सूची समझ में।
Xiong Chiamiov

9
आप नकारात्मक सूचकांक के मामले को भूल गए हैं। उदाहरण के लिए। index == -1000000लौट जाना चाहिए default
नोडाकाई

3
@ododai, अच्छी बात है। मुझे कभी-कभी इससे काट लिया गया है। x[index] if 0 <= index < len(x) else defaultबेहतर होगा यदि indexकभी नकारात्मक हो सकता है।
बेन होयट

3
@nodakai वाह - यह इस बात का एक बड़ा उदाहरण है कि परीक्षण को सही ढंग से कोड करने की कोशिश करने की तुलना में कोशिश / छोड़कर उपयोग करना बेहतर हो सकता है, इसलिए यह कभी भी विफल नहीं होता है। मैं अभी भी एक ऐसे मामले के लिए कोशिश करना / छोड़ना पसंद नहीं करता, जो मुझे पता है कि होगा, लेकिन यह इस पर विचार करने की मेरी इच्छा को बढ़ाता है।
टूलमेकरसेव

6
@ToolmakerSteve: आपका फॉर्मूला valid_index()गलत है। पायथन में नकारात्मक सूचकांक वैध हैं - यह होना चाहिए -len(l) <= index < len(l)
टिम पीटरसन

57
try:
   a = b[n]
except IndexError:
   a = default

संपादित करें: मैंने टाइपऑइर के लिए चेक को हटा दिया - शायद बेहतर होगा कि कॉलर इसे संभाल लें।


3
यह मुझे पंसद है। बस इसे एक फ़ंक्शन के चारों ओर लपेटें ताकि आप इसे तर्क के रूप में चलने के साथ कह सकें। पढ़ने में आसान।
नौफाल इब्राहिम

35
(a[n:]+[default])[0]

यह शायद बेहतर है क्योंकि aबड़ा हो जाता है

(a[n:n+1]+[default])[0]

यह काम करता है क्योंकि अगर a[n:]एक खाली सूची है अगरn => len(a)

यहाँ एक उदाहरण है कि यह कैसे काम करता है range(5)

>>> range(5)[3:4]
[3]
>>> range(5)[4:5]
[4]
>>> range(5)[5:6]
[]
>>> range(5)[6:7]
[]

और पूर्ण अभिव्यक्ति

>>> (range(5)[3:4]+[999])[0]
3
>>> (range(5)[4:5]+[999])[0]
4
>>> (range(5)[5:6]+[999])[0]
999
>>> (range(5)[6:7]+[999])[0]
999

5
क्या आप इसे समझाने के लिए टिप्पणी के बिना वास्तविक कोड में लिखेंगे?
पीटर हैनसेन

1
@ पेटर हेंसन, केवल तभी जब मैं गोल्फ कर रहा था;) हालाँकि यह पायथन के सभी संस्करणों पर काम करता है । स्वीकृत उत्तर केवल 2.5+ पर काम करता है
जॉन ला रोय

3
हालांकि, यह 3 अस्थायी सूचियों का निर्माण करता है और किसी वस्तु का चयन करने के लिए 2 सूचकांकों तक पहुंच बनाता है।
जोआचिम Jablon

हालांकि मैं इसे "वास्तविक" कोड में कभी नहीं करूंगा, यह एक अच्छा संक्षिप्त वन-लाइनर है जिसे मैं आसानी से एक अजगर REPL में उपयोग कर सकता हूं, इसलिए आप मेरे अपवोट प्राप्त करें।
कुक

next(iter(lst[i:i+1]), default)- क्रिप्टोकरेंसी बदसूरत वन-लाइनर्स प्रतियोगिता में सिर्फ एक और प्रविष्टि।
JFS

28

अभी पता चला है कि:

next(iter(myList), 5)

iter(l)पर एक पुनरावृत्ति देता है myList, next()पुनरावृत्ति के पहले तत्व का उपभोग करता है, और एक StopIterationत्रुटि उठाता है अगर डिफ़ॉल्ट मान के साथ बुलाया जाता है, जो कि यहां मामला है, दूसरा तर्क,5

यह केवल तब काम करता है जब आप 1 तत्व चाहते हैं, जो आपके उदाहरण में मामला है, लेकिन आपके प्रश्न के पाठ में नहीं, इसलिए ...

इसके अतिरिक्त, इसे मेमोरी में अस्थायी सूची बनाने की आवश्यकता नहीं है और यह किसी भी प्रकार के चलने योग्य के लिए काम करता है, भले ही इसका कोई नाम न हो (देखें ग्रूसज़ज़ी के जवाब पर जिओंग चुआमोव की टिप्पणी)


3
अन्य उत्तरों के साथ संयुक्त: next(iter(myList[n:n+1]), 5) अब यह nतत्व के लिए काम करता है।
अल्फ

यह गैर सूचियों के साथ काम नहीं करेगा। इस बिंदु पर, कोशिश करें: इंडेक्सएर्र को छोड़कर आईएनजी एक बेहतर विचार आईएमएचओ की तरह पढ़ता है। इसके अलावा, यह स्मृति में एक सूची बनाता है।
जोआचिम जाबलोन

tryसंस्करण एक एक लाइनर (ओपी द्वारा लिए कहा पूछें) नहीं है। यह केवल सूचियों के लिए काम करता है क्योंकि myListओपी द्वारा निर्दिष्ट एक सूची है (सटीक होने के लिए, यह कुछ अनुक्रमित है)। स्मृति में प्रतिलिपि बनाना यहाँ महंगा नहीं है क्योंकि मैं यहाँ एक एकल (या कोई भी) तत्व की सूची नहीं बना रहा हूँ। यकीन है, एक छोटे से उपरि, लेकिन उल्लेख के लायक नहीं है जब तक आप एक लूप में लाखों बार ऐसा नहीं करते हैं। Btw, मुझे लगता है कि एक IndexErrorअपवाद बनाना और पकड़ना शायद अधिक महंगा है।
अल्फ

पठनीयता मायने रखती है :) यदि आप उस बिंदु पर हैं जहां एक IndexError को उठाना एक महत्वपूर्ण लागत है, तो शायद आपको पायथन में पूरी बात करनी चाहिए।
जोआचिम जाबलोन

20
(L[n:n+1] or [somedefault])[0]

1
+1 क्योंकि इससे मुझे पता चला कि मैंने क्या [] or ...किया। हालांकि, मैं व्यक्तिगत रूप से केवल स्वीकृत समाधान का उपयोग करूंगा, क्योंकि यह आसानी से (नौसिखियों के लिए) पढ़ता है। दी गई, टिप्पणी के साथ इसे 'डिफ' में लपेटना काफी हद तक गैर-मुद्दा होगा।
टूलमेकरसैट

क्या होगा अगर L[n] == Falseया L[n] == Noneया L[n] == []विश्व स्तर पर कुछ भी जो फाल्स का मूल्यांकन करता है?
जोकिम Jablon

@ जोकिमजबलॉन: अभी भी काम करता है। टुकड़ा एक सूची देता है, और [False]सच है।
इग्नासियो वाज़क्वेज़-अब्राम्स

ओह, महसूस नहीं किया गया था कि सूची की जाँच की गई थी और मूल्य नहीं, वास्तव में।
जोचिम Jablon

आप इसे टुप में क्यों लपेटते हैं? मुझे लगता है कि myval = l[n:n+1] or [somedefault]ठीक काम करेगा?
रोटारटी

8

... dict.get(key, default)सूची के लिए अजगर में एक बराबर की तलाश में

वहाँ एक itertools व्यंजनों है कि यह सामान्य iterables के लिए करता है। सुविधा के लिए, आप > pip install more_itertoolsइस तृतीय-पक्ष पुस्तकालय को आयात और आयात कर सकते हैं जो आपके लिए ऐसे व्यंजनों को लागू करता है:

कोड

import more_itertools as mit


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

mit.nth([], 0, 5)
# 5    

विस्तार

यहाँ nthनुस्खा का कार्यान्वयन है :

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

जैसे dict.get(), यह उपकरण लापता सूचकांकों के लिए एक डिफ़ॉल्ट लौटाता है। यह सामान्य पुनरावृत्तियों पर लागू होता है:

mit.nth((0, 1, 2), 1)                                      # tuple
# 1

mit.nth(range(3), 1)                                       # range generator (py3)
# 1

mit.nth(iter([0, 1, 2]), 1)                                # list iterator 
# 1  

2

एक सस्ता समाधान वास्तव में एनुमरेट के साथ एक तानाशाही बनाना है और .get()हमेशा की तरह उपयोग करना है

 dict(enumerate(l)).get(7, my_default)

1

@ जोकिम के उपरोक्त के साथ, आप उपयोग कर सकते हैं

next(iter(my_list[index:]), default)

उदाहरण:

next(iter(range(10)[8:]), 11)
8
>>> next(iter(range(10)[12:]), 11)
11

या, शायद अधिक स्पष्ट है, लेकिन बिना len

my_list[index] if my_list[index:] else default

1

इसी तरह की contextlib.suppress(exceptions)एक getitem()विधि का निर्माण करने के लिए पायथन 3.4 का उपयोग करना getattr()

import contextlib

def getitem(iterable, index, default=None):
    """Return iterable[index] or default if IndexError is raised."""
    with contextlib.suppress(IndexError):
        return iterable[index]
    return default
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.