পাইথনে list.index (সম্ভবত অস্তিত্বহীন) হ্যান্ডেল করার সর্বোত্তম উপায়?


113

আমার কোড রয়েছে যা দেখতে কিছুটা এমন দেখাচ্ছে:

thing_index = thing_list.index(thing)
otherfunction(thing_list, thing_index)

ঠিক আছে তাই এটি সরলীকৃত তবে আপনি ধারণা পাবেন। এখন thingসম্ভবত তালিকায় নাও থাকতে পারে, সেক্ষেত্রে আমি -1 পাস করতে চাই thing_index। অন্যান্য ভাষায় এটি হ'ল আপনি index()যদি ফিরে আসার প্রত্যাশা করেন যদি এটি উপাদানটি খুঁজে না পায়। আসলে এটি নিক্ষেপ করে ValueError

আমি এটি করতে পারি:

try:
    thing_index = thing_list.index(thing)
except ValueError:
    thing_index = -1
otherfunction(thing_list, thing_index)

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

thing_index = ( [(i for i in xrange(len(thing_list)) if thing_list[i]==thing)] or [-1] )[0]

একই জিনিস অর্জন করার একটি ক্লিনার উপায় আছে? ধরে নেওয়া যাক তালিকাটি বাছাই করা হয়নি।


4
"... যে ক্ষেত্রে আমি -১ পাশ করতে চাই thing_index।" - এটি অবশ্যই অ-পাইথোনিক। কোনও অপারেশন সফল না হওয়ার ক্ষেত্রে একটি (অর্থহীন) টোকেন মানটি সাফল্যজনক না হলে - ব্যতিক্রমগুলি এখানে সঠিক উপায়। বিশেষত যেহেতু thing_list[-1]একটি বৈধ এক্সপ্রেশন, যার অর্থ তালিকার শেষ এন্ট্রি।
টিম পিটজ্যাকার

@ জেলিবিয়ান: ফেসপাম ... জাভা কোডারটিকে স্পট করুন: পি
ড্রিমন

4
@ টিম: এমন একটি str.findপদ্ধতি রয়েছে যা হুবহু এটি করে: ফিরে আসে -1যখন সূচকে বিষয় পাওয়া যায় না।
সাইলেন্টগোস্ট

@ টিম তখনকার চেয়ে ভাল আর কিছু হবে না ... এবং এটি ডিক [কী] বনাম ডিক.কেট [কী]
ড্রিমন

@ সাইলেন্টগোস্ট: এইচএম, আকর্ষণীয়। আমাকে আরও বিশদে এটি দেখতে হবে। str.index()অনুসন্ধানের স্ট্রিংটি পাওয়া না গেলে একটি ব্যতিক্রম ছুঁড়ে ফেলে।
টিম পিটজেকার

উত্তর:


65

ক্লজ ব্যতীত চেষ্টা ব্যতীত ব্যবহার সম্পর্কে "নোংরা" কিছুই নেই। এটি পাইথোনিক উপায়। কেবলমাত্র পদ্ধতি ValueErrorদ্বারা উত্থাপিত হবে .index, কারণ এটি আপনার কাছে কেবলমাত্র কোড!

মন্তব্যের জবাব দেওয়ার জন্য:
পাইথনে, অনুমতি পাওয়ার চেয়ে ক্ষমা চাওয়া সহজতর দর্শনটি সুপ্রতিষ্ঠিত, এবং অন্য কোনও index সমস্যার জন্য এই ধরণের ত্রুটি উত্থাপন করবে না। এমন যে আমি কারও কথা ভাবতে পারি না।


29
অবশ্যই ব্যতিক্রম ব্যতিক্রমী মামলার ক্ষেত্রে এবং এটি খুব কমই। যদি ভ্যালুআরারের চেয়ে ব্যতিক্রমটি আরও নির্দিষ্ট করা হত তবে আমার এমন সমস্যা হবে না।
ড্রাগন

1
আমি জানি এটি কেবল সেই পদ্ধতি থেকে নিক্ষেপ করা যেতে পারে তবে কেবল সেই কারণেই এটি ছুঁড়ে ফেলার নিশ্চয়তা কি? এমন নয় যে আমি অন্য কারণ সূচকটি ব্যর্থ হওয়ার কথা ভাবতে পারি..কিন্তু সেইসব জিনিসগুলির ব্যতিক্রমগুলি কি আপনি ভাবেন না?
ড্রাগন

4
{}.get(index, '')বেশি পাইথোনিক না ? সংক্ষিপ্ততর আরও পড়ার জন্য উল্লেখ করা উচিত নয়।
এস্তেবান কাবার

1
আমি অভি [Key] ব্যবহার যখন আমি কী করতে এবং বিদ্যমান dict.get (কী) যখন আমি নিশ্চিত নই আশা, এবং আমি আছি এখানে কিছু সমতুল্য খুঁজছেন। রিটার্নিং Noneপরিবর্তে -1 জরিমানা হতে পারে, কিন্তু নিজের মত মন্তব্য, str.find () আয় -1 তাই list.find কেন না সেখানে উচিত () যে একই জিনিস করে? আমি "
পাইথোনিক

3
তবে মুল বক্তব্যটি হ'ল সর্বাধিক পাইথোনিক দ্রবণটি হ'ল -1 সেন্ডিনেল মানটি নয় তবে কেবল চেষ্টা / বাদ দিয়ে ব্যবহার করা । আইই আপনার পুনর্লিখন করা উচিত otherfunction। অন্যদিকে, যদি এটি না ভাঙে, ...
অ্যান্ড্রু জাফি

53
thing_index = thing_list.index(elem) if elem in thing_list else -1

এক লাইন. সহজ। কোন আশা নাই.


35
হ্যাঁ সরল, তবে এটি দুটি রৈখিক অনুসন্ধান করবে এবং পারফরম্যান্স প্রতি-সে-ই কোনও সমস্যা নয়, এটি অত্যধিক বলে মনে হচ্ছে।
ড্রইমন

4
@ ড্রেমন: সম্মত হন - এটি ২ টি পাস করবে - তবে এটি সম্ভবত সম্ভাবনা নেই যে হাজার-লাইনের কোড-বেস থেকে এটির একটি বাধা হয়ে দাঁড়াবে। :) একজন সর্বদা এর সাথে একটি অত্যাবশ্যকীয় সমাধানের জন্য বেছে নিতে পারেন for
এমিল ইভানভ

মেষশাবক সহindexOf = lambda item,list_ : list_.index(item) if item in list_ else -1 # OR None
আলা আকিয়েল

17

dictটাইপ টি getফাংশন , যেখানে যদি চাবি অভিধানে বিদ্যমান নয়, এর 2nd যুক্তি getমান ফেরত হবে। অনুরূপভাবে রয়েছে setdefault, যা dictকী উপস্থিত থাকলে মানটিকে প্রদান করে , অন্যথায় এটি আপনার ডিফল্ট প্যারামিটার অনুযায়ী মান সেট করে এবং তারপরে আপনার ডিফল্ট প্যারামিটারটি দেয়।

আপনি listএকটি getindexdefaultপদ্ধতি আছে টাইপ প্রসারিত করতে পারে ।

class SuperDuperList(list):
    def getindexdefault(self, elem, default):
        try:
            thing_index = self.index(elem)
            return thing_index
        except ValueError:
            return default

যা তখন ব্যবহার করা যেতে পারে:

mylist = SuperDuperList([0,1,2])
index = mylist.getindexdefault( 'asdf', -1 )

6

আপনার কোড ব্যবহার করে তাতে কোনও ভুল নেই ValueError। আপনি যদি ব্যতিক্রমগুলি এড়াতে চান তবে এখানে আরও একটি ওয়ান-লাইনার রয়েছে:

thing_index = next((i for i, x in enumerate(thing_list) if x == thing), -1)

অজগরটি কি 2.6? আমি জানি আমি এটি উল্লেখ করি নি, তবে আমি 2.5 ব্যবহার করছি। এটি সম্ভবত আমি 2.6-এ করব
ড্রিমন

1
@ ড্রেমন: হ্যাঁ, next()পাইথন ২.6++ এ ফাংশন বিদ্যমান। তবে 2.5 এর জন্য বাস্তবায়ন করা সহজ, পরবর্তী () পাইথন 2.5
jfs

4

এই ইস্যুটি ভাষা দর্শনের একটি। উদাহরণস্বরূপ জাভাতে সর্বদা একটি beenতিহ্য রয়েছে যে ব্যতিক্রমগুলি কেবল "ব্যতিক্রমী পরিস্থিতিতে" ব্যবহার করা উচিত যখন ত্রুটিগুলি ঘটেছিল প্রবাহ নিয়ন্ত্রণের পরিবর্তে । শুরুতে এটি কার্য সম্পাদনের কারণে ছিল কারণ জাভা ব্যতিক্রমগুলি ধীর ছিল তবে এখন এটি গ্রহণযোগ্য স্টাইলে পরিণত হয়েছে।

বিপরীতে পাইথন সর্বদা স্বাভাবিক প্রোগ্রাম প্রবাহকে ইঙ্গিত করতে ব্যতিক্রম ব্যবহার করেছে, ValueErrorযেমনটি আমরা এখানে আলোচনা করছি raising পাইথন স্টাইলে এ সম্পর্কে "নোংরা" কিছুই নেই এবং এখান থেকে আরও অনেকগুলি এসেছে। আরও সাধারণ উদাহরণ StopIterationব্যতিক্রম যা কোনও পুনরাবৃত্তির next()পদ্ধতির দ্বারা উত্থাপিত হয় এটি নির্দেশ করার জন্য যে কোনও মান নেই।


আসলে, JDK ছোঁড়ার উপায় অনেকগুলি চেক করা ব্যতিক্রম, তাই আমি নিশ্চিত না যে দর্শনের আসলে জাভা প্রয়োগ করা হয় আছি। আমার প্রতি প্রতি সমস্যা নেই StopIterationকারণ ব্যতিক্রমটি কী তা এটি স্পষ্টভাবে সংজ্ঞায়িত হয়েছে। ValueErrorএকটু বেশি জেনেরিক is
ড্রয়মন

আমি ধারণা যে ব্যতিক্রম প্রবাহ নিয়ন্ত্রণের জন্য ব্যবহার করা উচিত নয় উল্লেখ করা হল, c2.com/cgi/wiki?DontUseExceptionsForFlowControl , না, তাই অনেক পরীক্ষিত ব্যতিক্রম সংখ্যা জাভা যা একটি সম্পূর্ণ অন্য আলোচনা হয়েছে যে: mindview.net/Etc/Discussions / পরীক্ষিত মতামত
টেন্ডাই মাওউশ

4

আপনি যদি প্রায়শই এটি করে থাকেন তবে এটি কোনও সহায়ক ফাংশনে স্টোভ করা ভাল:

def index_of(val, in_list):
    try:
        return in_list.index(val)
    except ValueError:
        return -1 

4

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

li = [1,2,3,4,5] # create list 

li = dict(zip(li,range(len(li)))) # convert List To Dict 
print( li ) # {1: 0, 2: 1, 3: 2, 4:3 , 5: 4}
li.get(20) # None 
li.get(1)  # 0 

1

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

otherfunction(thing_collection, thing)

ফাংশন ইন্টারফেসে একটি তালিকা সূচকের মতো বাস্তবায়ন-নির্ভর কিছু প্রকাশ করার পরিবর্তে সংগ্রহ এবং জিনিসটি পাস করুন এবং "সদস্যতার জন্য পরীক্ষা" ইস্যুগুলির সাথে অন্যটি কাজ করুন। যদি অন্যান্য ফাংশনটি সংগ্রহ-টাইপ-অজোনস্টিক হিসাবে লেখা হয় তবে সম্ভবত এটি দিয়ে শুরু হবে:

if thing in thing_collection:
    ... proceed with operation on thing

জিনিস_পরিবর্তনটি যদি একটি তালিকা, টুপল, সেট বা ডিক হয় তবে এটি কাজ করবে।

এটি সম্ভবত এর থেকে পরিষ্কার:

if thing_index != MAGIC_VALUE_INDICATING_NOT_A_MEMBER:

আপনার ইতিমধ্যে অন্য ফাংশনে কোডটি কী।



0

তালিকাগুলিতে ".index ()" পদ্ধতিতে আমার একই সমস্যা রয়েছে। এটি একটি ব্যতিক্রম ছুঁড়ে ফেলেছে তা নিয়ে আমার কোনও সমস্যা নেই তবে আমি এটি দৃ a়তার সাথে একমত নয় যে এটি একটি অ-বর্ণনামূলক ভ্যালুএরর। যদিও বুঝতে পারি এটি যদি একটি সূচিপত্র হয়, তবে।

আমি দেখতে পাচ্ছি কেন "-1" ফিরিয়ে দেওয়া কেন একটি সমস্যা হবে কারণ এটি পাইথনের একটি বৈধ সূচক। তবে বাস্তবে , আমি কখনই একটি ".index ()" পদ্ধতিটি নেতিবাচক সংখ্যা ফেরত প্রত্যাশা করি না

এখানে একটি লাইনার চলে গেছে (ঠিক আছে, এটি একটি দীর্ঘ লাইন ...), একবারে একবারে তালিকার মধ্য দিয়ে যায় এবং আইটেমটি পাওয়া না গেলে "কিছুই না" ফেরত দেয়। আপনার যদি ইচ্ছা হয় তবে এটি ফিরতি -1 এ পুনর্লিখন করা তুচ্ছ হবে।

indexOf = lambda list, thing: \
            reduce(lambda acc, (idx, elem): \
                   idx if (acc is None) and elem == thing else acc, list, None)

ব্যবহারবিধি:

>>> indexOf([1,2,3], 4)
>>>
>>> indexOf([1,2,3], 1)
0
>>>

-2

আমি জানি না কেন আপনি এটি নোংরা ভাবেন ... ব্যতিক্রমের কারণে? আপনি যদি অনলাইনার চান তবে এটি এখানে:

thing_index = thing_list.index(elem) if thing_list.count(elem) else -1

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


1
হ্যাঁ, ব্যতিক্রম কারণ। আপনার কোড দুটি লিনিয়ার অনুসন্ধান করবে না? না পারফরম্যান্স এখানে সত্যিই গুরুত্বপূর্ণ। সুপারডুপারলিস্ট সমাধানটি দুর্দান্ত তবে এই বিশেষ পরিস্থিতিতে ওভারকিলের মতো বলে মনে হচ্ছে। আমি মনে করি আমি কেবল ব্যতিক্রমটি শেষ করব, তবে আমি দেখতে চেয়েছিলাম যে কোনও ক্লিনার (আমার নান্দনিকতার জন্য) উপায় আছে কিনা।
ড্রইমন

@ ড্রেমন: ভাল আপনি নিজের কোডটি ফাংশনটিতে সজ্জিত find()করবেন এবং এটি সমস্ত পরিষ্কার হয়ে যাবে;)
সাইলেন্টগোস্ট

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

-2

আমি পরামর্শ দেব:

if thing in thing_list:
  list_index = -1
else:
  list_index = thing_list.index(thing)

2
এই সমাধানটিতে সমস্যা হ'ল "-1" হল তালিকার একটি বৈধ সূচক (শেষ সূচক; শেষ থেকে প্রথম)। এটি পরিচালনা করার সর্বোত্তম উপায় হ'ল আপনার অবস্থার প্রথম শাখায় মিথ্যা ফিরানো।
FanaticD
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.