पायथन में ट्यूपल्स की सूची कैसे खोजें


90

तो मेरे पास इस तरह के tuples की एक सूची है:

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

मुझे यह सूची एक टुपल के लिए चाहिए, जिसकी संख्या का मूल्य कुछ के बराबर है।

ताकि अगर मैं ऐसा search(53)करता हूं तो इसका सूचकांक मूल्य वापस आ जाएगा2

क्या इसे करने का कोई आसान तरीका है?

जवाबों:


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

68
क्या आप समझाएंगे?
Schatten

17
शब्दों में समझाया गया है: प्रत्येक i के लिए, v, L की गणना की गई सूची में (जो कि गणना की सूची में तत्व की स्थिति बनाता है और v का मूल tuple है) जाँच करें कि क्या tuple का पहला तत्व 53 है, यदि ऐसा है, तो कोड का परिणाम जोड़ें नव निर्मित सूची के लिए 'से पहले', यहाँ: i। यह my_function (i, v) या अभी तक एक अन्य सूची समझ हो सकती है। चूँकि आपकी tuples की सूची में पहले मान के रूप में 53 के साथ एक tuple है, इसलिए आपको एक तत्व के साथ एक सूची मिलेगी।
djangonaut

6
मैं सिर्फ [i for i, v in enumerate (L) को जोड़ना चाहूंगा अगर v [0] == 53] .pop () में इंट वैल्यू हो।
अनामुल


47

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

व्याख्या

ऐसे कई उत्तर हैं जो सूची के प्रश्नों के साथ इस प्रश्न का एक सरल समाधान प्रदान करते हैं। हालांकि ये जवाब पूरी तरह से सही हैं, लेकिन वे इष्टतम नहीं हैं। आपके उपयोग के मामले के आधार पर, कुछ सरल संशोधन करने के लिए महत्वपूर्ण लाभ हो सकते हैं।

इस उपयोग के मामले के लिए एक सूची समझ का उपयोग करने के साथ मैं जो मुख्य समस्या देख रहा हूं वह यह है कि पूरी सूची संसाधित हो जाएगी, हालांकि आप केवल इस तत्व को खोजना चाहते हैं ।

पायथन एक सरल निर्माण प्रदान करता है जो यहां आदर्श है। इसे जनरेटर अभिव्यक्ति कहा जाता है । यहाँ एक उदाहरण है:

# 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()हमारे जनरेटर से पहली वस्तु प्राप्त करने के लिए उपयोग करेंगे ।

आइए देखें कि कैसे ये तरीके कुछ बड़े डेटा सेटों पर अलग-अलग प्रदर्शन करते हैं। ये बड़ी सूचियाँ हैं, जो 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}

क्या?! सबसे अच्छा मामला सूची समझ को नष्ट कर देता है, लेकिन मैं इस हद तक सूची की समझ को बेहतर बनाने के लिए हमारे सबसे खराब मामले की उम्मीद नहीं कर रहा था। यह कैसा है? सच कहूँ तो, मैं केवल और अधिक शोध के बिना अटकलें लगा सकता था।

नमक के दाने के साथ यह सब ले लो, मैंने यहां कोई मजबूत रूपरेखा नहीं बनाई है, बस कुछ बहुत ही बुनियादी परीक्षण। यह सराहना करने के लिए पर्याप्त होना चाहिए कि इस प्रकार की सूची खोज के लिए एक जनरेटर अभिव्यक्ति अधिक निष्पादित है।

ध्यान दें कि यह सभी बुनियादी, अंतर्निहित अजगर है। हमें कुछ भी आयात करने या किसी लाइब्रेरी का उपयोग करने की आवश्यकता नहीं है।

मैंने पहली बार पीटर नॉरविग के साथ उनेसिटी सीएस 212 कोर्स में खोज करने के लिए इस तकनीक को देखा ।


2
दिलचस्प है, मैंने परीक्षण किया और वास्तव में तेजी से पाया
बृजेश चौहान

3
यह स्वीकृत उत्तर होना चाहिए। जेनरेटर एक्सप्रेशंस पूरे आउटपुट सीक्वेंस को मटियामेट नहीं करते हैं, जब वे चलते हैं, बल्कि वे एक इटरेटर का मूल्यांकन करते हैं जो एक्सप्रेशन से एक बार में एक आइटम की उपज देता है।
बोल्त्ज़मैनब्रैन

2
यह बहुत अच्छा है, मेरे मामले में एक सूची की तुलना में बहुत तेजी से, धन्यवाद!
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]

2
अगर हम नजरअंदाज करते हैं कि वास्तव में ओपी ने क्या मांगा है, तो मुझे लगता है कि आपका प्रारंभिक उत्तर "पायथन में ट्यूपल्स की सूची कैसे खोजें" का सबसे अच्छा जवाब है
रिक वेस्टेरा

आपका पहला उत्तर मेरे उद्देश्यों के लिए उपयोगी था। हो सकता है कि उपयोग करने के लिए बेहतर हो। भूल () हालांकि, मद में नहीं है। l = [(1,"juca"),(22,"james"),(53,"xuxa"),(44,"delicia")] val = dict(l).get(53)
user1503941

12

हम्म ... ठीक है, सरल तरीका जो मन में आता है उसे एक तानाशाही में बदलना है

d = dict(thelist)

और पहुंच d[53]

संपादित करें : उफ़, पहली बार आपके प्रश्न को गलत बताया। ऐसा लगता है कि आप वास्तव में सूचकांक प्राप्त करना चाहते हैं जहां एक दी गई संख्या संग्रहीत है। उस मामले में, प्रयास करें

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

एक सादे पुराने dictरूपांतरण के बजाय । तब d[53]2 होगा।


6

सूची मान लंबा हो सकता है और संख्या, दोहराने का उपयोग कर विचार कर सकते हैं SortedList से प्रकार अजगर sortedcontainers मॉड्यूल । SortedList प्रकार स्वचालित रूप से संख्या द्वारा tuples बनाए रखने और तेजी से खोज के लिए अनुमति देगा।

उदाहरण के लिए:

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 के लिए बाइसेक्टिंग करके, हम अपने स्लाइस के लिए अंतिम इंडेक्स पाएंगे। स्वीकृत उत्तर की तुलना में लंबी सूचियों पर यह काफी तेज होगा।



-1

[k के लिए k, v में l अगर v == ' डेलिशिया ']

यहाँ l tuples की सूची है - [(1, "juca"), (22, "james"), (53, "xuxa"), (44, "delicia")]

और इसे एक तानाशाही में परिवर्तित करने के बजाय, हम लिस्ट की समझ का उपयोग कर रहे हैं।

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


हाँ यकीनन। साभार @cosmoonot
मेन्तेज सिंह

यहाँ l tuples की सूची है - [(1, "juca"), (22, "james"), (53, "xuxa"), (44, "delicia")] और इसके बजाय इसे एक तानाशाह में बदलने के लिए। हम लिस्टल कॉम्प्रिहेंशन का उपयोग कर रहे हैं। ` कुंजी कुंजी, सूची में मूल्य, में जहां मूल्य = Delicia `
Mantej सिंह
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.