मुझे लगता ओपी इस inplace करना चाहती है।
ऑपरेशन को तेजी से बनाने की कुंजी सूचियों के निर्माण को कम करना और सूचियों को छोटा करना/विस्तार करना है। इसका मतलब है कि हमें हमेशा सूची सूचकांक के 1: 1 असाइनमेंट करने का प्रयास करना चाहिए, इसलिए L[i:i] = L[a:b]
और L[a:b] = []
नहीं। insert
और pop
के साथ लूप का उपयोग करना और भी बदतर है, क्योंकि तब आप सूची को कई बार छोटा और लंबा करते हैं। Concatenating सूचियां भी खराब है क्योंकि आपको पहले प्रत्येक भाग के लिए एक सूची बनाना है और फिर प्रत्येक +
के लिए एक बार बड़ी और बड़ी समेकित सूचियां बनाना है। चूंकि आप इसे "इनस्थल" करना चाहते हैं, इसलिए आपको जेनरेट की गई सूची को अंत में L[:]
पर असाइन करना होगा।
# items: 0 | 1 2 3 | 4 5 6 7 | 8 9
# a span1 b span2 c
# pos: 1 4 8
# Result:
# 0 | 4 5 6 7 | 1 2 3 | 8 9
# a span2 span2 c
पहले अवलोकन करें। यदि a = start
, b = end = start + length
, और c
सम्मिलित स्थिति है, तो हम जिस ऑपरेशन को करना चाहते हैं वह |
मार्करों पर कटौती करना है और span1
और span2
स्वैप करना है।लेकिन अगर b = start
और c = end
और a
सम्मिलित स्थिति है, तो हम भीspan1
और span2
स्वैप करना चाहते हैं। तो हमारे कार्य में, हम केवल दो लगातार खंडों से निपटते हैं जिन्हें स्वैप किया जाना चाहिए।
हम पूरी तरह से नई सूचियां बनाने से नहीं बच सकते हैं, क्योंकि हमें सामानों को स्थानांतरित करते समय ओवरलैपिंग मानों को स्टोर करने की आवश्यकता है। हम कर सकते हैं, हालांकि एक अस्थायी सूची में स्टोर करने के लिए दो स्पैन चुनने के द्वारा, जितनी छोटी हो सके सूची को कम से कम बनाएं।
def inplace_shift(L, start, length, pos):
if pos > start + length:
(a, b, c) = (start, start + length, pos)
elif pos < start:
(a, b, c) = (pos, start, start + length)
else:
raise ValueError("Cannot shift a subsequence to inside itself")
if not (0 <= a < b < c <= len(L)):
msg = "Index check 0 <= {0} < {1} < {2} <= {3} failed."
raise ValueError(msg.format(a, b, c, len(L)))
span1, span2 = (b - a, c - b)
if span1 < span2:
tmp = L[a:b]
L[a:a + span2] = L[b:c]
L[c - span1:c] = tmp
else:
tmp = L[b:c]
L[a + span2:c] = L[a:b]
L[a:a + span2] = tmp
कोस अपने समय में कोई त्रुटि की है लगता है, इसलिए मैं तर्क को सही (end
start
और length
से की गणना) के बाद अपने कोड के साथ उन्हें redid, और इन परिणामों कर रहे हैं, धीरे से करने के लिए सबसे तेजी से।
Nick Craig-Wood: 100 loops, best of 3: 8.58 msec per loop
vivek: 100 loops, best of 3: 4.36 msec per loop
PaulP.R.O. (deleted?): 1000 loops, best of 3: 838 usec per loop
unbeli: 1000 loops, best of 3: 264 usec per loop
lazyr: 10000 loops, best of 3: 44.6 usec per loop
मैंने परीक्षण नहीं किया है कि अन्य किसी भी दृष्टिकोण से सही परिणाम मिलते हैं।
तुम कैसे जानते हो कि सी, डी, ई आइटम आप ले जाना चाहते हैं? क्या वे निश्चित स्थिति हैं, या आप मूल्यों की जांच कर रहे हैं? –
क्या होगा यदि उपन्यास सम्मिलन बिंदु को ओवरलैप करता है? –
यह संभव नहीं है, @ lazyr का जवाब भी इसे रोकता है। – TTT