2017-02-06 15 views
18

this post से मुझे पता चला कि आप के साथ tuples जोड़ सकते हैं:जुटना योग को tuples()

>>> tuples = (('hello',), ('these', 'are'), ('my', 'tuples!')) 
>>> sum(tuples,()) 
('hello', 'these', 'are', 'my', 'tuples!') 

जो काफी अच्छा लग रहा है। लेकिन यह क्यों काम करता है? और, यह इष्टतम है, या itertools से कुछ ऐसा है जो इस निर्माण के लिए बेहतर होगा?

+0

यह कार्य क्यों नहीं करना चाहिए? यह सिर्फ एक साथ tuples जोड़ रहा है, लेकिन यह विशेष रूप से कुशल नहीं है। [Itertools.chain] पर एक नज़र डालें (https://docs.python.org/3/library/itertools.html#itertools.chain)। उदाहरण के लिए, 'tuple (श्रृंखला (* tuples)) ' –

+0

@ पीएम 2Ring। 'चेन' का उपयोग करने से बचें क्योंकि यह' sum' से भी अधिक अक्षम है (जब तक कि टुपल्स का संग्रह बहुत छोटा न हो)। इसके बजाए 'chain.from_iterable' का प्रयोग करें। – ekhumoro

+0

@ekhumoro ओह! हां, chain.from_iterable बेहतर है। और जैसा कि बोउड के जवाब से पता चलता है, यह वास्तव में tuples के छोटे संग्रह के लिए राशि से धीमा है। –

उत्तर

19

अजगर में इसके अलावा ऑपरेटर कोनकैटेनेट्स tuples:

('a', 'b')+('c', 'd') 
Out[34]: ('a', 'b', 'c', 'd') 

sum की docstring से:

वापसी एक 'स्टार्ट' मान का योग (डिफ़ॉल्ट: 0) के साथ साथ का एक iterable संख्या

इसका मतलब है sum आपके पुनरावर्तनीय के पहले तत्व से शुरू नहीं होता है, लेकिन बल्कि start= तर्क के माध्यम से पारित प्रारंभिक मान के साथ।

डिफ़ॉल्ट रूप से sum संख्यात्मक के साथ प्रयोग किया जाता है इस प्रकार डिफ़ॉल्ट प्रारंभ मान 0 है। तो tuples के एक पुनरावर्तनीय संक्षेप में एक खाली tuple के साथ शुरू करने की आवश्यकता है। () एक खाली ट्यूपल है:

type(()) 
Out[36]: tuple 

इसलिए कामकाजी संगतता।

%timeit sum(tuples,()) 
The slowest run took 9.40 times longer than the fastest. This could mean that an intermediate result is being cached. 
1000000 loops, best of 3: 285 ns per loop 


%timeit tuple(it.chain.from_iterable(tuples)) 
The slowest run took 5.00 times longer than the fastest. This could mean that an intermediate result is being cached. 
1000000 loops, best of 3: 625 ns per loop 
एक आकार 10000 के t2 साथ

अब:

%timeit sum(t2,()) 
10 loops, best of 3: 188 ms per loop 

%timeit tuple(it.chain.from_iterable(t2)) 
1000 loops, best of 3: 526 µs per loop 

तो अगर tuples की अपनी सूची छोटा है, आपको परेशान नहीं है

प्रति प्रदर्शन के रूप में, यहाँ एक तुलना है। यदि यह मध्यम आकार या बड़ा है, तो आपको itertools का उपयोग करना चाहिए।

+0

दिलचस्प समय। आपने किस पायथन संस्करण का उपयोग किया था? –

+0

@ पीएम 2Ring 3.5 64 बिट्स – Boud

+0

'सर्वश्रेष्ठ 3' => कृपया ipython – Boud

5

चालाक है कि और मैं हँसने क्योंकि मदद स्पष्ट रूप से तार की मनाही थी, लेकिन

sum(...) 
    sum(iterable[, start]) -> value 

    Return the sum of an iterable of numbers (NOT strings) plus the value 
    of parameter 'start' (which defaults to 0). When the iterable is 
    empty, return start. 

आप एक नया, बड़ा टपल पाने के लिए tuples जोड़ सकते हैं काम करता है। और चूंकि आपने प्रारंभ मूल्य के रूप में एक tuple दिया है, अतिरिक्त काम करता है।

+0

में% समय-समय पर प्रलेखन का संदर्भ लें इस उदाहरण में,' sum' ने तारों को सम्मिलित नहीं किया है: इसमें दो स्ट्रिंग्स शामिल नहीं हैं जो इनपुट में अलग थे यहाँ। (उदा। 'हैलो 'का उपयोग करके' हैलो 'और' दुनिया 'को' helloworld' में बदलने का कोई तरीका नहीं है।) – ShreevatsaR

+1

आईएमओ जो पाइथन करता है वह बेवकूफ है। योग '+' ऑपरेटर का समर्थन करने वाली किसी भी चीज़ को पूरा करने में सक्षम होना चाहिए। स्ट्रिंग्स करते हैं। निष्पादन और अच्छे सम्मेलन के नाम पर तारों के लिए विशेष मामला स्पष्ट रूप से अस्वीकार कर रहा है (जबकि पाइथन में अन्य एंटीपेटर्न की अनुमति नहीं है) केवल अच्छी डिजाइन नहीं है – progo

+0

@ShreevatsaR मुझे इसके बारे में काफी जानकारी है। सहायता तारों का उल्लेख करती है लेकिन मैंने यह बताने के लिए कहा कि यह वास्तव में tuples जोड़ रहा है। मैंने सोचा कि यह मनोरंजक था और माना जाता है कि लोग पढ़ सकते हैं। – tdelaney

0

बस कुछ और बेंचमार्क के साथ स्वीकार किए जाते हैं जवाब पूरक:

import functools, operator, itertools 
import numpy as np 
N = 10000 
M = 2 

ll = np.random.random((N, M)).tolist() 

विकल्प 1:

%timeit functools.reduce(operator.add, ll) 
359 ms ± 6.11 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) 

विकल्प 2:

%timeit functools.reduce(lambda x, y: x + y, ll) 
327 ms ± 1.71 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) 

विकल्प 3:

%timeit sum(ll,()) 
324 ms ± 2.28 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) 

विकल्प 4:

%timeit itertools.chain(*ll) 
70.3 µs ± 249 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each) 

विकल्प 5:

%timeit itertools.chain.from_iterable(ll) 
254 ns ± 3.61 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)