পাইথনে টিপলগুলির একটি তালিকা কীভাবে অনুসন্ধান করবেন


91

সুতরাং আমার কাছে এর মতো টিপলগুলির একটি তালিকা রয়েছে:

[(1,"juca"),(22,"james"),(53,"xuxa"),(44,"delicia")]

আমি এই তালিকার এমন একটি টুপলের জন্য চাই যার সংখ্যার মান কোনও কিছুর সমান।

যাতে আমি যদি search(53)এটি করি তবে এর সূচক মানটি ফিরে আসবে2

এটি করার কোনও সহজ উপায় আছে?

উত্তর:


95
[i for i, v in enumerate(L) if v[0] == 53]

69
আপনি দয়া করে ব্যাখ্যা করবেন?
স্কেচেন

17
কথায় বর্ণিত: প্রতিটি আই এর জন্য, এল এর একটি তালিকাভুক্ত তালিকায় (যেটি আমি তালিকাভুক্ত তালিকায় উপাদানটির অবস্থান তৈরি করে এবং মূল টিপলকে v করে তোলে) টিউলের প্রথম উপাদানটি 53 হয় কিনা তা পরীক্ষা করে দেখুন, যদি থাকে তবে কোডটির ফলাফল যুক্ত করুন নতুন তৈরি তালিকায় 'for' এর আগে, এখানে: i। এটি my_function (i, v) বা অন্য একটি তালিকা বোধগম্যতাও হতে পারে। যেহেতু আপনার টিপলগুলির তালিকায় প্রথম মান হিসাবে 53 টির সাথে কেবল একটি টিপল রয়েছে, আপনি একটি উপাদান সহ একটি তালিকা পাবেন।
jাঙোনাট

6
আমি কেবলমাত্র [i এর জন্য i, v গণনা (এল) এর সাথে যোগ করব যদি ভি [0] == 53]। পপ () এর মান মান থাকে।
আলেমল

50

tl; ডা

একটি জেনারেটর এক্সপ্রেশন সম্ভবত আপনার সমস্যার সর্বাধিক পারফরম্যান্ট এবং সহজ সমাধান:

l = [(1,"juca"),(22,"james"),(53,"xuxa"),(44,"delicia")]

result = next((i for i, v in enumerate(l) if v[0] == 53), None)
# 2

ব্যাখ্যা

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

এই ব্যবহারের ক্ষেত্রে তালিকার বোঝাপড়াটি ব্যবহার করে আমি যে প্রধান সমস্যাটি দেখছি তা হ'ল সম্পূর্ণ তালিকাটি প্রক্রিয়া করা হবে, যদিও আপনি কেবল 1 টি উপাদান খুঁজে পেতে চান ।

পাইথন একটি সাধারণ কনস্ট্রাক্ট সরবরাহ করে যা এখানে আদর্শ। একে জেনারেটর এক্সপ্রেশন বলে । এখানে একটি উদাহরণ:

# Our input list, same as before
l = [(1,"juca"),(22,"james"),(53,"xuxa"),(44,"delicia")]

# Call next on our generator expression.
next((i for i, v in enumerate(l) if v[0] == 53), None)

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

কিছু বড় ডেটা সেটগুলিতে এই পদ্ধতিগুলি কীভাবে আলাদাভাবে সম্পাদন করে তা দেখুন look শুরুতে (সেরা) বা শেষ (খারাপ) আমাদের টার্গেট সহ এগুলি 10000000 + 1 উপাদানগুলির তৈরি বড় তালিকা। আমরা যাচাই করতে পারি যে এই দুটি তালিকা নীচের তালিকার বোধগম্যতা ব্যবহার করে সমানভাবে সম্পাদন করবে:

বোধগম্য তালিকা

"নিকৃষ্ট ঘটনা"

worst_case = ([(False, 'F')] * 10000000) + [(True, 'T')]
print [i for i, v in enumerate(worst_case) if v[0] is True]

# [10000000]
#          2 function calls in 3.885 seconds
#
#    Ordered by: standard name
#
#    ncalls  tottime  percall  cumtime  percall filename:lineno(function)
#         1    3.885    3.885    3.885    3.885 so_lc.py:1(<module>)
#         1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

"সর্বোত্তম ঘটনা"

best_case = [(True, 'T')] + ([(False, 'F')] * 10000000)
print [i for i, v in enumerate(best_case) if v[0] is True]

# [0]
#          2 function calls in 3.864 seconds
#
#    Ordered by: standard name
#
#    ncalls  tottime  percall  cumtime  percall filename:lineno(function)
#         1    3.864    3.864    3.864    3.864 so_lc.py:1(<module>)
#         1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

জেনারেটর এক্সপ্রেশন

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

নিকৃষ্ট ঘটনা

# 10000000
#          5 function calls in 1.733 seconds
#
#    Ordered by: standard name
#
#    ncalls  tottime  percall  cumtime  percall filename:lineno(function)
#         2    1.455    0.727    1.455    0.727 so_lc.py:10(<genexpr>)
#         1    0.278    0.278    1.733    1.733 so_lc.py:9(<module>)
#         1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
#         1    0.000    0.000    1.455    1.455 {next}

সর্বোত্তম ঘটনা

best_case  = [(True, 'T')] + ([(False, 'F')] * 10000000)
print next((i for i, v in enumerate(best_case) if v[0] == True), None)

# 0
#          5 function calls in 0.316 seconds
#
#    Ordered by: standard name
#
#    ncalls  tottime  percall  cumtime  percall filename:lineno(function)
#         1    0.316    0.316    0.316    0.316 so_lc.py:6(<module>)
#         2    0.000    0.000    0.000    0.000 so_lc.py:7(<genexpr>)
#         1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
#         1    0.000    0.000    0.000    0.000 {next}

কি?! সেরা ক্ষেত্রে তালিকার বোধগম্যতা দূরে সরিয়ে দেয়, তবে আমি আমাদের খারাপ পরিস্থিতিটি তালিকা বোধগম্যতা এতটা ছাড়িয়ে যাওয়ার আশা করছিলাম না। ওটা কেমন? সত্যি বলতে কী, আমি কেবল আরও গবেষণা ছাড়াই অনুমান করতে পারি।

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

দ্রষ্টব্য যে এটি সমস্ত মৌলিক, অন্তর্নির্মিত পাইথন। আমাদের কিছু আমদানি বা কোনও লাইব্রেরি ব্যবহার করার দরকার নেই।

আমি পিটার নরভিগের সাথে উদাসিটি সিএস 1212 কোর্সে অনুসন্ধান করার জন্য এই কৌশলটি প্রথম দেখলাম ।


4
আকর্ষণীয়, আমি এটি পরীক্ষা করেছি এবং এটির সত্যই দ্রুত পেয়েছি
গ্রিজেশ চৌহান

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

4
এটি দুর্দান্ত, আমার ক্ষেত্রে তালিকার বোঝার চেয়ে অনেক দ্রুত, ধন্যবাদ!
mindm49907


29

আপনার টিপলগুলি মূলত মূল-মান জোড়া - একটি অজগর - তাই dict:

l = [(1,"juca"),(22,"james"),(53,"xuxa"),(44,"delicia")]
val = dict(l)[53]

সম্পাদনা - আহা, আপনি বলেছেন যে আপনি সূচকের মান চান (53, "xuxa")। আপনি যদি চান এটি যদি সত্যিই হয় তবে আপনাকে মূল তালিকাটি পুনরাবৃত্তি করতে হবে, বা সম্ভবত আরও জটিল অভিধান তৈরি করতে হবে:

d = dict((n,i) for (i,n) in enumerate(e[0] for e in l))
idx = d[53]

4
যদি আমরা ওপি আসলে যা চেয়েছিল তা উপেক্ষা করি তবে আমি মনে করি যে আপনার প্রাথমিক উত্তরটি "পাইথনের
টিউপসগুলির

আপনার প্রথম উত্তরটি আমার উদ্দেশ্যে কার্যকর ছিল was আইটেমটি ডিকটিতে না থাকলেও .get () ব্যবহার করা ভাল। l = [(1,"juca"),(22,"james"),(53,"xuxa"),(44,"delicia")] val = dict(l).get(53)
ব্যবহারকারী1503941

12

হুম ... ঠিক আছে, মনে আসার সহজ উপায় হ'ল এটিকে ডিকে রূপান্তর করা

d = dict(thelist)

এবং অ্যাক্সেস d[53]

সম্পাদনা : ওফস, আপনার প্রশ্নটি প্রথমবার ভুলভাবে লিখুন। দেখে মনে হচ্ছে আপনি একটি সূচিত পেতে চান যেখানে একটি প্রদত্ত নম্বর সঞ্চয় করা আছে। সেক্ষেত্রে চেষ্টা করুন

dict((t[0], i) for i, t in enumerate(thelist))

পরিবর্তে একটি সাধারণ পুরানো dictরূপান্তর। তাহলে d[53]2 হবে।


6

ধরুন, তালিকাটি দীর্ঘ হতে পারে এবং সংখ্যাগুলি পুনরাবৃত্তি হতে পারে, পাইথন सॉোর্টড কন্টেইনার মডিউল থেকে সোর্টার্ডলিস্ট প্রকারটি ব্যবহার বিবেচনা করুন । সাজানো তালিকার ধরণটি স্বয়ংক্রিয়ভাবে সংখ্যা অনুসারে টিপলগুলি বজায় রাখবে এবং দ্রুত অনুসন্ধানের জন্য অনুমতি দেবে।

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

from sortedcontainers import SortedList
sl = SortedList([(1,"juca"),(22,"james"),(53,"xuxa"),(44,"delicia")])

# Get the index of 53:

index = sl.bisect((53,))

# With the index, get the tuple:

tup = sl[index]

এটি বাইনারি অনুসন্ধান করে তালিকার বোঝার পরামর্শের চেয়ে অনেক দ্রুত কাজ করবে। অভিধানের পরামর্শটি এখনও ত্বরান্বিত হবে তবে যদি বিভিন্ন স্ট্রিংয়ের সাথে সদৃশ নম্বর থাকতে পারে তবে কাজ করবে না।

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

end = sl.bisect((53 + 1,))

results = sl[index:end]

54 এর জন্য দ্বিখণ্ডিত করে, আমরা আমাদের স্লাইসের জন্য শেষ সূচকটি খুঁজে পাব। স্বীকৃত উত্তরের তুলনায় দীর্ঘ তালিকাতে এটি উল্লেখযোগ্যভাবে দ্রুত হবে।



-2

[কে ফর কে, ভি ইন এল যদি ভি == ' ডেলিসিয়া ']

এখানে l টিপলগুলির তালিকা - [(1, "জুকা"), (22, "জেমস"), (53, "xuxa"), (44, "ডেলিসিয়া")]

এবং এটিকে কোনও ডিকে রূপান্তরিত করার পরিবর্তে আমরা তালিকাভুক্তি ব্যবহার করছি।

*Key* in Key,Value in list, where value = **delicia**


হ্যাঁ অবশ্যই. আপনাকে ধন্যবাদ
মনতেজ সিং

এখানে l টিপলগুলির তালিকা রয়েছে - [(1, "জুকা"), (22, "জেমস"), (53, "xuxa"), (44, "ডেলিসিয়া")] এবং এটিকে ডিকে রূপান্তরিত করার পরিবর্তে, আমরা তালিকাভুক্তি ব্যবহার করছি। ` কী কী, তালিকার মূল্য, যেখানে মান = delicia `
Mantej সিং
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.