में तारों को विभाजित करने का सबसे प्रभावी तरीका मेरे वर्तमान पायथन परियोजना को आने वाले पैकेजों को संसाधित करने के लिए बहुत सी स्ट्रिंग विभाजन की आवश्यकता होगी। चूंकि मैं इसे एक धीमी धीमी प्रणाली पर चला रहा हूं, इसलिए मैं सोच रहा था कि इसके बारे में जाने का सबसे प्रभावी तरीका क्या होगा। तार कुछ इस तरह से स्वरूपित किया जाएगा:पायथन
Item 1 | Item 2 | Item 3 <> Item 4 <> Item 5
स्पष्टीकरण: यह विशेष रूप से उदाहरण के लिए, एक सूची जहां पहले दो आइटम एक शीर्षक और एक तारीख कर रहे हैं से आएगा, जबकि आइटम 5 के लिए आइटम 3 लोगों को आमंत्रित किया जा सकता है (उनमें से संख्या शून्य से एन तक कुछ भी हो सकती है, जहां सर्वर पर पंजीकृत उपयोगकर्ताओं की संख्या है)।
से मैं क्या देखते हैं, मैं निम्नलिखित विकल्प हैं:
- बार-बार
split()
- रेगुलर एक्सप्रेशन का उपयोग का उपयोग करें और Regex
- कुछ अन्य अजगर कार्यों के बारे में मैं अभी तक नहीं सोचा कार्य करता है (हैं शायद कुछ)
समाधान 1 में |
पर विभाजन शामिल होगा और फिर परिणामस्वरूप सूची के अंतिम तत्व को विभाजित करना होगा इस उदाहरण के लिए <>
, जबकि समाधान 2 शायद की तरह एक नियमित अभिव्यक्ति में परिणाम होगा:
((.+)|)+((.+)(<>)?)+
ठीक है, यह रेगुलर एक्सप्रेशन से भयानक है, मुझे लगता है कि अपने आप को देख सकते हैं। यह भी अवांछित है। लेकिन आप विचार समझ गये।
अब, मैं इस तरह की तलाश कर रहा हूं कि ए) कम से कम समय लेता है और बी) आदर्श रूप से कम से कम स्मृति का उपयोग करता है। यदि दोनों में से केवल एक संभव है, तो मैं कम समय पसंद करूंगा। आदर्श समाधान स्ट्रिंग्स के लिए भी काम करेगा जिसमें |
और तारों की पूरी तरह से <>
की कमी है। कम से कम नियमित अभिव्यक्ति आधारित समाधान करना होगा कि
मेरे समझ होगा कि split()
अधिक स्मृति का प्रयोग करेंगे (जब से तुम मूल रूप से दो परिणामस्वरूप सूचियों, एक है कि |
और दूसरा एक है कि <>
पर विभाजन पर विभाजन मिलता है), लेकिन मुझे नियमित अभिव्यक्तियों के पाइथन क्रियान्वयन के बारे में पर्याप्त जानकारी नहीं है कि यह निर्णय लेने के लिए कि RegEx कैसे करेगा। split()
नियमित अभिव्यक्ति की तुलना में भी कम गतिशील है यदि यह आइटम की विभिन्न संख्याओं और दूसरे सेपरेटर की अनुपस्थिति में आता है।
- हाँ मैं कर सकता बस बेंचमार्क दोनों समाधान,, लेकिन मैं कर रहा हूँ: फिर भी, मैं छाप हिला नहीं कर सकता कि अजगर नियमित अभिव्यक्ति के बिना इस बेहतर कर सकते हैं, यही कारण है कि मैं
कुछ नोट पूछ रहा हूँ है सामान्य रूप से अजगर के बारे में कुछ सीखने की कोशिश कर रहा है और यह कैसे काम करता है, और यदि मैं इन दोनों को सिर्फ बेंचमार्क करता हूं, तो मुझे अभी भी पता नहीं है कि मैंने किस पायथन कार्यों को याद किया है।
- हां, इस स्तर पर अनुकूलित करने के लिए केवल उच्च प्रदर्शन सामग्री के लिए वास्तव में आवश्यक है, लेकिन जैसा कि मैंने कहा, मैं अजगर के बारे में चीजें सीखने की कोशिश कर रहा हूं।
- अलावा: मूल प्रश्न में, मैं पूरी तरह से है कि मैं (भागों कि विभाजक
<>
साथ भागों से|
से अलग कर रहे थे, तो एक साधारण फ्लैट सूची के रूप मेंre.split(\||<>,input)
द्वारा उत्पन्न भेद करने में सक्षम होने की जरूरत है उल्लेख करना भूल गया जैसा कि @obmarg द्वारा प्रस्तावित) बहुत अच्छी तरह से काम नहीं करेगा। इस मानदंड को फिट करने वाले समाधानों की बहुत सराहना की जाती है।
प्रश्न को समेटने के लिए: कौन सा समाधान सबसे प्रभावी होगा, किस कारण से।
import timeit
import re
def splitit(input):
res0 = input.split("|")
res = []
for element in res0:
t = element.split("<>")
if t != [element]:
res0.remove(element)
res.append(t)
return (res0, res)
def regexit(input):
return re.split("\||<>", input)
def mgibsonbr(input): # Solution by @mgibsonbr
items = re.split(r'\||<>', input) # Split input in items
offset = 0
result = [] # The result: strings for regular itens, lists for <> separated ones
acc = None
for i in items:
delimiter = '|' if offset+len(i) < len(input) and input[offset+len(i)] == '|' else '<>'
offset += len(i) + len(delimiter)
if delimiter == '<>': # Will always put the item in a list
if acc is None:
acc = [i] # Create one if doesn't exist
result.append(acc)
else:
acc.append(i)
else:
if acc is not None: # If there was a list, put the last item in it
acc.append(i)
else:
result.append(i) # Add the regular items
acc = None # Clear the list, since what will come next is a regular item or a new list
return result
def split2(input): # Solution by @duncan
res0 = input.split("|")
res1, res2 = [], []
for r in res0:
if "<>" in r:
res2.append(r.split("<>"))
else:
res1.append(r)
return res1, res2
print "mgibs:", timeit.Timer("mgibsonbr('a|b|c|de|f<>ge<>ah')","from __main__ import mgibsonbr").timeit()
print "split:", timeit.Timer("splitit('a|b|c|de|f<>ge<>ah')","from __main__ import splitit").timeit()
print "split2:", timeit.Timer("split2('a|b|c|de|f<>ge<>ah')","from __main__ import split2").timeit()
print "regex:", timeit.Timer("regexit('a|b|c|de|f<>ge<>ah')","from __main__ import regexit").timeit()
print "mgibs:", timeit.Timer("mgibsonbr('a|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>ah')","from __main__ import mgibsonbr").timeit()
print "split:", timeit.Timer("splitit('a|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>ah')","from __main__ import splitit").timeit()
print "split:", timeit.Timer("split2('a|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>ah')","from __main__ import split2").timeit()
print "regex:", timeit.Timer("regexit('a|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>aha|b|c|de|f<>ge<>ah')","from __main__ import regexit").timeit()
परिणाम:
अधिक अनुरोध के कारण, मैं split()
-solution पर कुछ timeit और @obmarg द्वारा पहले प्रस्तावित नियमित अभिव्यक्ति है, साथ ही @mgibsonbr और @duncan द्वारा समाधान चलाने :
mgibs: 14.7349407408
split: 6.403942732
split2: 3.68306812233
regex: 5.28414318792
mgibs: 107.046683735
split: 46.0844590775
split2: 26.5595985591
regex: 28.6513302646
फिलहाल, यह Split2 तरह से @duncan सभी अन्य एल्गोरिदम धड़कता है, (कम से कम इस सीमित डाटासेट के साथ) लग रहा है, भले ही लंबाई की, और यह भी लग रहा है @ mgibsonbr के समाधान की तरह कुछ प्रदर्शन के मुद्दों है (माफ करना 'बोउट कि, बी बिना किसी समाधान के समाधान के लिए धन्यवाद।
इनपुट के लिए धन्यवाद, हर कोई।
पर जाओ, बस 'timeit' का उपयोग करें और खुद के लिए देखते हैं। यह आसान है। मेरे दांव 'str.split' पर हैं। – wim
मुझे लगता है कि लंबी स्ट्रिंग के लिए, 're' तेज हो सकता है। लेकिन आपको सुनिश्चित करने के लिए बेंचमार्क करना होगा। – Dikei
मैं शर्त लगाता हूं कि यह आईओ बाध्य है। मेरा पहला अनुमान यह कहना होगा कि किसी भी प्रकार का विभाजन डिस्क या नेटवर्क से प्राप्त इनपुट से तेज़ होगा। –