मैं सब कुछ पहले कैसे प्राप्त करूंगा: एक स्ट्रिंग पायथन में


106

मैं एक से पहले एक पत्र में सभी अक्षरों को पाने के लिए एक रास्ता तलाश रहा हूं: लेकिन मुझे पता नहीं है कि कहां से शुरू करना है। क्या मैं regex का उपयोग करूंगा? यदि हां, तो कैसे?

string = "Username: How are you today?"

क्या कोई मुझे एक उदाहरण दिखा सकता है कि मैं क्या कर सकता हूं?

जवाबों:


177

बस splitफ़ंक्शन का उपयोग करें । यह एक सूची देता है, इसलिए आप पहला तत्व रख सकते हैं:

>>> s1.split(':')
['Username', ' How are you today?']
>>> s1.split(':')[0]
'Username'

12
या तो सीमित कर विभाजन, या इस मामले में - उपयोगs1.partition(':')[0]
जॉन क्लेमेंट्स

धन्यवाद, यह बहुत उपयोगी और ज्ञानवर्धक था। इसके अलावा यह एक बड़ी मदद धन्यवाद वा!
कूल

2
विभाजन का उपयोग न करें, क्योंकि यह सभी ':' को संसाधित कर रहा है और एक पूर्ण सरणी बनाता है, लंबे समय तक तार के लिए अच्छा नहीं है। एक सूचकांक का उपयोग करने के लिए @ Hackaholic का दृष्टिकोण देखें। बस वह भी एक regex की सिफारिश कर रहा है जो स्पष्ट रूप से उतना प्रभावी नहीं है। इसके अलावा .substringBefore () जो कि सूचकांक आधारित है, के मानक संचालन को करने के लिए एक अजगर विकल्प होना चाहिए। और भी विविधताएँ जैसे .substringBeforeLast (), आदि सुविधा के लिए होनी चाहिए (कोड दोहराया नहीं जाना चाहिए)। विभाजन के बारे में ध्यान देने योग्य बात है - हाँ, ':' के बाद कम प्रसंस्करण, लेकिन फिर भी '1' के बजाय <वर्ग 'टपल'>: ('1', ':', '2: 3') लौटाता है।
arntg

46

का उपयोग कर index:

>>> string = "Username: How are you today?"
>>> string[:string.index(":")]
'Username'

सूचकांक आपको :स्ट्रिंग में स्थिति देगा , फिर आप इसे स्लाइस कर सकते हैं।

यदि आप regex का उपयोग करना चाहते हैं:

>>> import re
>>> re.match("(.*?):",string).group()
'Username'                       

match स्ट्रिंग की शुरुआत से मेल खाता है।

आप भी उपयोग कर सकते हैं itertools.takewhile

>>> import itertools
>>> "".join(itertools.takewhile(lambda x: x!=":", string))
'Username'

3
इस विधि (स्ट्रिंग [: string.index (":")]) विभाजन की तुलना में शायद क्लीनर है
डेमियन

गति के लिए रेगेक्स का उपयोग न करें - यहां उल्लिखित पहले सूचकांक विकल्प का उपयोग करें। रेगेक्स स्पष्ट रूप से उतना प्रभावी नहीं है। इसके अलावा .substringBefore () जो कि सूचकांक आधारित है, के मानक संचालन को करने के लिए एक अजगर विकल्प होना चाहिए। और भी विविधताएँ जैसे .substringBeforeLast (), आदि सुविधा के लिए होनी चाहिए (कोड दोहराया नहीं जाना चाहिए)। इस उत्तर को अपडेट करने के लिए सुझाव दें कि यह इंडेक्स बेहतर क्यों काम करता है और फिर इसने फ़्रेड्टेंटिनी की प्रतिक्रिया में अब उच्च मतदान सहित अन्य तरीकों का उपयोग क्यों किया।
मेष

यदि यह मौजूद नहीं है, तो सूचकांक विफल हो जाएगा।
मार्क

19

आप की जरूरत नहीं है regexइस के लिए

>>> s = "Username: How are you today?"

आप चरित्र splitपर स्ट्रिंग को विभाजित करने के लिए विधि का उपयोग कर सकते हैं':'

>>> s.split(':')
['Username', ' How are you today?']

और [0]स्ट्रिंग का पहला भाग प्राप्त करने के लिए तत्व को बाहर करें

>>> s.split(':')[0]
'Username'

8

मैंने पायथन 3.7.0 (आईपीथॉन) के तहत इन विभिन्न टेकनीकों को बेंचमार्क किया है।

TLDR

  • सबसे तेज़ (जब विभाजित प्रतीक cज्ञात होता है): पूर्व-संकलित रेगेक्स।
  • सबसे तेज (अन्यथा) s.partition(c)[0]:।
  • सुरक्षित (यानी, जब cनहीं हो सकता है s): विभाजन, विभाजन।
  • असुरक्षित: इंडेक्स, रेगेक्स।

कोड

import string, random, re

SYMBOLS = string.ascii_uppercase + string.digits
SIZE = 100

def create_test_set(string_length):
    for _ in range(SIZE):
        random_string = ''.join(random.choices(SYMBOLS, k=string_length))
        yield (random.choice(random_string), random_string)

for string_length in (2**4, 2**8, 2**16, 2**32):
    print("\nString length:", string_length)
    print("  regex (compiled):", end=" ")
    test_set_for_regex = ((re.compile("(.*?)" + c).match, s) for (c, s) in test_set)
    %timeit [re_match(s).group() for (re_match, s) in test_set_for_regex]
    test_set = list(create_test_set(16))
    print("  partition:       ", end=" ")
    %timeit [s.partition(c)[0] for (c, s) in test_set]
    print("  index:           ", end=" ")
    %timeit [s[:s.index(c)] for (c, s) in test_set]
    print("  split (limited): ", end=" ")
    %timeit [s.split(c, 1)[0] for (c, s) in test_set]
    print("  split:           ", end=" ")
    %timeit [s.split(c)[0] for (c, s) in test_set]
    print("  regex:           ", end=" ")
    %timeit [re.match("(.*?)" + c, s).group() for (c, s) in test_set]

परिणाम

String length: 16
  regex (compiled): 156 ns ± 4.41 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
  partition:        19.3 µs ± 430 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
  index:            26.1 µs ± 341 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  split (limited):  26.8 µs ± 1.26 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  split:            26.3 µs ± 835 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  regex:            128 µs ± 4.02 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

String length: 256
  regex (compiled): 167 ns ± 2.7 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
  partition:        20.9 µs ± 694 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  index:            28.6 µs ± 2.73 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  split (limited):  27.4 µs ± 979 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  split:            31.5 µs ± 4.86 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  regex:            148 µs ± 7.05 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

String length: 65536
  regex (compiled): 173 ns ± 3.95 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
  partition:        20.9 µs ± 613 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
  index:            27.7 µs ± 515 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  split (limited):  27.2 µs ± 796 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  split:            26.5 µs ± 377 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  regex:            128 µs ± 1.5 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

String length: 4294967296
  regex (compiled): 165 ns ± 1.2 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
  partition:        19.9 µs ± 144 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
  index:            27.7 µs ± 571 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  split (limited):  26.1 µs ± 472 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  split:            28.1 µs ± 1.69 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
  regex:            137 µs ± 6.53 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

1
आप सूचकांक को असुरक्षित क्यों मानते हैं ?
जेम्स

3
s.index(c)जब cमें नहीं है एक ValueError उठाता है s। इसलिए, मैं इसे सुरक्षित मानता हूं जब मुझे यकीन है कि विभाजित होने वाले स्ट्रिंग में विभाजक, असुरक्षित अन्यथा शामिल हैं।
अरिस्टाइड

1
इंडेक्स के लिए, सी s में है, इसलिए यह असुरक्षित और अभी भी सबसे तेज नहीं है।
arntg

2

विभाजन () बेहतर हो सकता है तो इस उद्देश्य के लिए विभाजित () करें क्योंकि इसमें उन स्थितियों के लिए बेहतर पूर्वानुमान परिणाम हैं जिनके पास आपके पास कोई सीमांकक या अधिक सीमांकक नहीं है।


1
दोनों partitionऔर splitएक खाली स्ट्रिंग या कोई सीमांकक के साथ पारदर्शी रूप से काम करेंगे। यह ध्यान देने योग्य है कि word[:word.index(':')]इन दोनों मामलों में पॉप जाएगा।
रोब हॉल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.