पायथन में "उलट" सूची बनाने का सबसे अच्छा तरीका?


89

पायथन में, एक नई सूची बनाने का सबसे अच्छा तरीका क्या है जिसकी वस्तुएं किसी अन्य सूची के समान हैं, लेकिन रिवर्स ऑर्डर में? (मैं मौजूदा सूची को संशोधित नहीं करना चाहता।)

यहाँ एक समाधान है जो मेरे साथ हुआ है:

new_list = list(reversed(old_list))

डुप्लिकेट करना संभव है old_listतब डुप्लिकेट को उल्टा कर दें:

new_list = list(old_list) # or `new_list = old_list[:]`
new_list.reverse()

क्या कोई बेहतर विकल्प है जिसकी मैंने अनदेखी की है? यदि नहीं, तो क्या उपरोक्त कारणों में से किसी एक का उपयोग करने के लिए एक सम्मोहक कारण (जैसे दक्षता) है?

जवाबों:


205
newlist = oldlist[::-1]

[::-1]टुकड़ा करने की क्रिया (जो मेरी पत्नी अन्ना को "द मार्टियन स्माइली" कहलाना पसंद करती है; ;-) का अर्थ है: पूरे क्रम को टुकड़ा करना, -1 के एक कदम के साथ, अर्थात, उल्टा। यह सभी दृश्यों के लिए काम करता है।

ध्यान दें कि यह ( और आपके द्वारा उल्लिखित विकल्प) एक "उथले कॉपी" के बराबर है, अर्थात: यदि आइटम परस्पर हैं और आप उन पर म्यूटेटर कहते हैं, तो मूल सूची में रखे गए आइटमों में म्यूटेशन भी आइटम में हैं। उलटी सूची, और इसके विपरीत। यदि आपको इससे बचने की आवश्यकता है, copy.deepcopy(जबकि हमेशा एक संभावित महंगा ऑपरेशन), इस मामले में एक के बाद .reverse, एक ही अच्छा विकल्प है।


अरे बाप रे! यही कारण है कि है सुरुचिपूर्ण। कुछ दिनों पहले तक मुझे महसूस नहीं हुआ कि स्लाइस करते समय "कदम" को शामिल करना संभव है; अब मैं सोच रहा हूँ कि मैं इसके बिना कभी कैसे मिला! धन्यवाद, एलेक्स। :)
davidchambers

1
धन्यवाद, यह भी उल्लेख करने के लिए कि यह उथली प्रति पैदा करता है। हालांकि, मुझे इसकी आवश्यकता है, इसलिए मैं अपने कोड में एक मार्टी स्माइली जोड़ने वाला हूं।
davidchambers

13
यह वास्तव में बहुत अधिक जादू लगता है और मूल सुझाव की तुलना में बहुत कम पठनीय है list(reversed(oldlist))। एक लघु सूक्ष्म अनुकूलन के अलावा, क्या कोई पसंद [::-1]करने का कोई कारण है reversed()?
ब्रायन कैंपबेल

@ ब्रायनकैम्पबेल: इसके बारे में "जादू" क्या है? यदि आप सभी को समझने की कोशिश कर रहे हैं, तो यह कुल समझ में आता है। यदि आप स्लाइसिंग ... को अच्छी तरह से नहीं समझते हैं, तो आपको वास्तव में अपने पायथन करियर में इसे जल्दी सीखना चाहिए। reversedजब आपको सूची की आवश्यकता नहीं है, तो निश्चित रूप से इसका एक बड़ा फायदा है , क्योंकि यह मेमोरी या अप-फ्रंट समय इसे बनाने में बर्बाद नहीं करता है। लेकिन आप जब कर सूची की जरूरत है, का उपयोग कर [::-1]के बजाय list(reversed())का उपयोग कर एक के अनुरूप है [listcomp]के बजाय list(genexpr)
बजे

10
@abarnert कोड में मैं काम करता हूं, मैं शायद ही कभी तीसरे स्लाइस तर्क को देखता हूं, अगर मुझे इसका उपयोग दिखाई देता है तो मुझे यह देखना होगा कि इसका क्या मतलब है। एक बार जब मैं करता हूं, यह अभी भी स्पष्ट नहीं है कि कदम शुरू होने पर डिफ़ॉल्ट शुरू और अंत मानों की अदला-बदली होती है। त्वरित नज़र में, तीसरे तर्क के अर्थ को देखे बिना, मैं अनुमान लगा सकता हूं कि [::-1]इसका मतलब है कि सूची के अंतिम तत्व को हटाने के बजाय, इसे उल्टा करना। reversed(list)बताता है कि वास्तव में यह क्या कर रहा है; यह अपने आशय को स्पष्ट करता है, "स्पष्ट से बेहतर है निहित", "पठनीयता मायने रखता है", और "विरल घने से बेहतर है"।
ब्रायन कैंपबेल

56

अब चलो timeitसंकेत: एलेक्स का [::-1]सबसे तेज :)

$ p -m timeit "ol = [1, 2, 3]; nl = list(reversed(ol))"
100000 loops, best of 3: 2.34 usec per loop

$ p -m timeit "ol = [1, 2, 3]; nl = list(ol); nl.reverse();"
1000000 loops, best of 3: 0.686 usec per loop

$ p -m timeit "ol = [1, 2, 3]; nl = ol[::-1];"
1000000 loops, best of 3: 0.569 usec per loop

$ p -m timeit "ol = [1, 2, 3]; nl = [i for i in reversed(ol)];"
1000000 loops, best of 3: 1.48 usec per loop


$ p -m timeit "ol = [1, 2, 3]*1000; nl = list(reversed(ol))"
10000 loops, best of 3: 44.7 usec per loop

$ p -m timeit "ol = [1, 2, 3]*1000; nl = list(ol); nl.reverse();"
10000 loops, best of 3: 27.2 usec per loop

$ p -m timeit "ol = [1, 2, 3]*1000; nl = ol[::-1];"
10000 loops, best of 3: 24.3 usec per loop

$ p -m timeit "ol = [1, 2, 3]*1000; nl = [i for i in reversed(ol)];"
10000 loops, best of 3: 155 usec per loop

अपडेट: इंस्पेक्टर जी 4 डग द्वारा सुझाई गई सूची सूची विधि। मैं परिणामों को अपने लिए बोलने देता हूँ।


8
बस एक नोट - यह उलटी कॉपी सूची बनाने के लिए सटीक है, लेकिन उलटा अभी भी पुनरावृत्ति के लिए अधिक कुशल है[::-1]
तदह मैकडॉनल्ड्स-जेनसेन

7

समायोजन

यह sdolan द्वारा समय गणना के लिए एक बेसलाइन बेंचमार्क / समायोजन प्रदान करने के लायक है जो अक्सर अनावश्यक list()रूपांतरण के बिना 'उलट' के प्रदर्शन को दिखाता है । यह list()ऑपरेशन रनटाइम में एक अतिरिक्त 26 usecs जोड़ता है और केवल एक ईटरेटर अस्वीकार्य होने की स्थिति में इसकी आवश्यकता होती है।

परिणाम:

reversed(lst) -- 11.2 usecs

list(reversed(lst)) -- 37.1 usecs

lst[::-1] -- 23.6 usecs

गणना:

# I ran this set of 100000 and came up with 11.2, twice:
python -m timeit "ol = [1, 2, 3]*1000; nl = reversed(ol)"
100000 loops, best of 3: 11.2 usec per loop

# This shows the overhead of list()
python -m timeit "ol = [1, 2, 3]*1000; nl = list(reversed(ol))"
10000 loops, best of 3: 37.1 usec per loop

# This is the result for reverse via -1 step slices
python -m timeit "ol = [1, 2, 3]*1000;nl = ol[::-1]"
10000 loops, best of 3: 23.6 usec per loop

निष्कर्ष:

इन परीक्षणों का निष्कर्ष 12.4 usecs द्वारा reversed()स्लाइस से तेज है[::-1]


15
उलट () एक पुनरावृत्ति वस्तु देता है जो आलसी-मूल्यांकन किया जाता है, इसलिए मुझे लगता है कि यह सामान्य रूप से स्लाइस अंकन [:: - 1] की तुलना में उचित नहीं है।
इंद्रधनुषी

1
यहां तक ​​कि ऐसे मामले में जहां एक पुनरावृत्ति सीधे इस्तेमाल किया जा सकता है, जैसे कि ''.join(reversed(['1','2','3'])), स्लाइस विधि अभी भी> 30% तेज है।
डैंसलमो

1
कोई आश्चर्य नहीं कि आपको पहले 2 परीक्षणों से एक ही परिणाम क्यों मिला: वे समान हैं!
MestreLion

मेरे परिणाम अधिक बारीकी से मिलते-जुलते हैं। ol [:: - 1] सूची (उलट (ol)) के रूप में लंबे समय के बारे में दो बार लेता है। Ol [:: - 1] विधि लिखने के लिए कम वर्ण लेता है। हालाँकि, सूची (उलट (ol)) शायद शुरुआती अजगर प्रोग्रामर के लिए अधिक पठनीय है और यह मेरी मशीन पर तेज़ है।
dhj
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.