2009-08-20 13 views
302

में एक सूची को वापस करने के लिए एक मानचित्र() प्राप्त करना मैं हेक्स में एक सूची को मैप करने की कोशिश कर रहा हूं, और फिर सूची को कहीं और उपयोग कर रहा हूं। अजगर 2.6 में, यह आसान था:पाइथन 3.x

एक: अजगर 2.6:

>>> map(chr, [66, 53, 0, 94]) 
['B', '5', '\x00', '^'] 

हालांकि, अजगर 3.1 पर, ऊपर एक नक्शा वस्तु देता है।

बी: अजगर 3.1:

>>> map(chr, [66, 53, 0, 94]) 
<map object at 0x00AF5570> 

मैं कैसे मैप की सूची प्राप्त करते अजगर 3.x पर (ऊपर एक के रूप में)?

वैकल्पिक रूप से, क्या ऐसा करने का एक बेहतर तरीका है? मेरी प्रारंभिक सूची ऑब्जेक्ट में लगभग 45 आइटम हैं और आईडी उन्हें हेक्स में परिवर्तित करना है।

+0

@meawoppl नीचे मेरा उत्तर देखें http://stackoverflow.com/a/24507069/17523 –

उत्तर

462

यह करें:

list(map(chr,[66,53,0,94])) 

अजगर 3+ में, कई प्रक्रियाओं है कि iterables से अधिक पुनरावृति iterators खुद को लौट आते हैं। ज्यादातर मामलों में, यह स्मृति को सहेजता है, और चीजों को तेज़ी से बढ़ाना चाहिए।

तो तुम सब करने जा रहे हैं अंत में इस सूची पर पुनरावृति है, वहाँ भी यह एक सूची में बदलने की कोई आवश्यकता नहीं है, क्योंकि आप अभी भी map वस्तु इतनी तरह से अधिक पुनरावृति कर सकते हैं:

# Prints "ABCD" 
for ch in map(chr,[65,66,67,68]): 
    print(ch) 
+1

महान स्पष्टीकरण के लिए धन्यवाद !! – mozami

+10

बेशक, आप इस पर भी पुन: प्रयास कर सकते हैं: (x (65,66,67,68] में x के लिए chr (x))। इसे मानचित्र की भी आवश्यकता नहीं है। – hughdbrown

+0

@hughdbrown 3 का उपयोग करने के लिए तर्क।एक जटिल कार्य, बड़े डेटा सेट, या धाराओं पर पुनरावृत्ति करते समय 1 का 'नक्शा' आलसी मूल्यांकन होगा। –

70

आप ऐसा क्यों कर नहीं कर रहे हैं:

[chr(x) for x in [66,53,0,94]] 

यह एक सूची समझ कहा जाता है। आप Google पर बहुत सारी जानकारी पा सकते हैं, लेकिन here's the link to the Python (2.6) documentation on list comprehensions। हालांकि, the Python 3 documenation में आपको अधिक रुचि हो सकती है।

+8

हां समझने के लिए हाँ। – hughdbrown

+4

हम्मम्म। हो सकता है कि सूची समझ, जनरेटर, मानचित्र(), ज़िप(), और अजगर में कई अन्य त्वरित पुनरावृत्ति भलाई पर एक सामान्य पोस्टिंग की आवश्यकता हो। – hughdbrown

+23

मुझे लगता है क्योंकि यह अधिक वर्बोज़ है, आपको एक अतिरिक्त चर (दो बार) लिखना है ... यदि ऑपरेशन अधिक जटिल है और आप एक लैम्ब्डा लिखना समाप्त कर देते हैं, या आपको कुछ तत्वों को छोड़ने की भी आवश्यकता है, तो मुझे लगता है कि एक समझ निश्चित रूप से है मानचित्र + फ़िल्टर से बेहतर, लेकिन यदि आपके पास पहले से ही वह फ़ंक्शन है जिसे आप लागू करना चाहते हैं, तो मानचित्र अधिक संक्षिप्त है। – fortran

11

मैं मैं पाइथन 3.1 से परिचित नहीं हूं, लेकिन क्या यह काम करेगा?

[chr(x) for x in [66, 53, 0, 94]] 
+1

पूरी तरह से काम करता है। – ExceptionSlayer

18

सूची-वापसी मानचित्र फ़ंक्शन को टाइपिंग सहेजने का लाभ है, खासकर इंटरैक्टिव सत्रों के दौरान। आप lmap समारोह (को Python2 के imap के सादृश्य पर) परिभाषित कर सकते हैं कि सूची लौटाती है:

lmap = lambda func, *iterable: list(map(func, *iterable) 

फिर map के बजाय lmap बुला काम करेगा: lmap(str, x) 5 अक्षर (इस मामले में 30%) की तुलना में से कम है list(map(str, x)) और [str(v) for v in x] से निश्चित रूप से छोटा है। आप filter के लिए भी समान कार्य बना सकते हैं।

मूल प्रश्न के लिए एक टिप्पणी थी:

मैं नक्शा() हो रही है पायथन 3. में एक सूची वापस जाने के लिए * के रूप में यह सब python3 संस्करणों पर लागू होता करने के लिए एक नाम बदलने का सुझाव देते हैं। क्या इसे करने का कोई तरीका है? - meawoppl जनवरी 24 17:58

यह पर कि ऐसा करना संभव है, लेकिन यह एक बहुत बुरा विचार है।सिर्फ मनोरंजन के लिए, यहाँ है कि कैसे आप (लेकिन चाहिए ) यह कर सकते हैं:

__global_map = map #keep reference to the original map 
lmap = lambda func, *iterable: list(__global_map(func, *iterable)) # using "map" here will cause infinite recursion 
map = lmap 
x = [1, 2, 3] 
map(str, x) #test 
map = __global_map #restore the original map and don't do that again 
map(str, x) #iterator 
43

नए और साफ अजगर 3.5 में:

[*map(chr, [66, 53, 0, 94])] 

धन्यवाद Additional Unpacking Generalizations को

+6

'सूची() 'में क्या गलत है? – Quelklef

+2

@Quelklef 'list()' साफ-सुथरा – Arijoon

+1

@Quelklef के रूप में नहीं दिखता है: इसके अलावा, अनपॅकिंग दृष्टिकोण 'सूची' कन्स्ट्रक्टर को देखने और सामान्य फ़ंक्शन कॉल मशीनरी को देखने की आवश्यकता के लिए बहुत तेज़ धन्यवाद है। एक लंबे इनपुट के लिए, इससे कोई फर्क नहीं पड़ता; एक छोटे से के लिए, यह एक बड़ा अंतर कर सकते हैं। उपरोक्त कोड को 'tuple' के रूप में इनपुट के साथ उपयोग करना, इसलिए इसे बार-बार पुनर्निर्मित नहीं किया जाता है,' ipython' microbenchmarks 'सूची()' रैपिंग दृष्टिकोण को अनपॅक करने से लगभग 20% अधिक समय लगता है। आपको पूर्ण शब्दों में, हम 150 एनएस के बारे में बात कर रहे हैं, जो तुच्छ है, लेकिन आपको विचार मिलता है। – ShadowRanger

0
list(map(chr, [66, 53, 0, 94])) 

मानचित्र (func, * iterables) -> नक्शा ऑब्जेक्ट एक इटरेटर बनाएं जो आपको फ़ंक्शन की गणना करता है से प्रत्येक पुनरावृत्तियों से तर्क गाएं। बंद हो जाता है जब सबसे कम पुनरावृत्त समाप्त हो जाता है।

"पुनरावर्तक बनाओ" का अर्थ है यह एक इटरेटर वापस आ जाएगी।

"iterables में से प्रत्येक से तर्कों का उपयोग समारोह की गणना करता है कि" इसका मतलब है कि इटरेटर के अगले() फ़ंक्शन प्रत्येक iterables में से एक मान ले और एक स्थितीय के लिए उनमें से प्रत्येक के पास होगा समारोह का पैरामीटर।

तो आपको मानचित्र() funtion से एक पुनरावर्तक मिलता है और jsut इसे सूची() अंतर्निहित फ़ंक्शन या सूची समझों का उपयोग करता है।

1

बेहतर दृश्यता के लिए परिवर्तित my old comment: एक के बिना map पूरी तरह से, आपके इनपुट ASCII ऑर्डिनल्स माने जाते रहे हैं, यह आम तौर पर बहुत तेजी से bytes और डिकोड, एक ला bytes(list_of_ordinals).decode('ascii') कन्वर्ट करने के लिए है "बेहतर तरीका यह करने के लिए" के लिए। यह आपको मानों के str प्राप्त करता है, लेकिन अगर आपको list की आवश्यकता है या आप इसे बदलने के लिए चाहते हैं, तो आप इसे परिवर्तित कर सकते हैं (और यह अभी भी तेज़ है)। उदाहरण के लिए, ipython microbenchmarks में 45 आदानों परिवर्तित:

>>> %%timeit -r5 ordinals = list(range(45)) 
... list(map(chr, ordinals)) 
... 
3.91 µs ± 60.2 ns per loop (mean ± std. dev. of 5 runs, 100000 loops each) 

>>> %%timeit -r5 ordinals = list(range(45)) 
... [*map(chr, ordinals)] 
... 
3.84 µs ± 219 ns per loop (mean ± std. dev. of 5 runs, 100000 loops each) 

>>> %%timeit -r5 ordinals = list(range(45)) 
... [*bytes(ordinals).decode('ascii')] 
... 
1.43 µs ± 49.7 ns per loop (mean ± std. dev. of 5 runs, 1000000 loops each) 

>>> %%timeit -r5 ordinals = list(range(45)) 
... bytes(ordinals).decode('ascii') 
... 
781 ns ± 15.9 ns per loop (mean ± std. dev. of 5 runs, 1000000 loops each) 

आप एक str के रूप में यह छोड़ देते हैं तो यह ~ लेता है सबसे तेजी से map समाधान के समय का 20%; यहां तक ​​कि सूची में वापस परिवर्तित करना यह अभी भी सबसे तेज़ map समाधान का 40% से कम है। थोक परिवर्तित के माध्यम से bytes और bytes.decode तो list वापस करने के लिए परिवर्तित प्रकार भारी मात्रा में, काम, लेकिन बताया गया है की एक बहुत कुछ बचाता है केवल (latin-1 चरित्र लोकेल विशिष्ट एन्कोडिंग प्रति कुछ एक बाइट में या ऑर्डिनल्स, उदा) काम करता है, तो आपके सभी आदानों ASCII ऑर्डिनल्स हैं।

संबंधित मुद्दे