% S को {0}, {1} ... कम क्लंकी में कैसे बदलें?


11

मुझे बाद में प्रतिस्थापन के लिए एक स्ट्रिंग युक्त प्लेसहोल्डर्स लेना होगा, जैसे:

"A %s B %s"

और उसे चालू करें:

"A {0} B {1}"

मेरे द्वारा लाया गया:

def _fix_substitution_parms(raw_message):
  rv = raw_message
  counter = 0
  while '%s' in rv:
    rv = rv.replace('%s', '{' + str(counter) + '}', 1)
    counter = counter + 1
return rv

यह काम करता है, लेकिन यह सुपर क्लंकी लगता है, और सभी "मुहावरेदार" अजगर नहीं है।

एक अच्छा, मुहावरेदार अजगर समाधान कैसे दिखेगा?

स्पष्टीकरण के लिए अपडेट:

  • परिणामी तारों का उपयोग अजगर के भीतर नहीं किया जाता है। मैं कर वहाँ में काउंटर संख्या की जरूरत है! (इसलिए {}बहुत अच्छा नहीं है)!
  • मुझे केवल %sस्ट्रिंग्स के बारे में परवाह करने की ज़रूरत है , क्योंकि संदेशों को केवल उपयोग करने की गारंटी है %s(कोई %i %fभी)

"re.sub" एक फ़ंक्शन को गतिशील रूप से क्रमांकित ब्रेसिज़ के साथ बदलने के लिए ले सकता है। वैसे: संख्या के बिना {} के साथ प्रतिस्थापित करना भी काम करेगा।
— माइकल बुचर

3
जब आपके पास एक कार्यशील समाधान हो और आप इसे सुधारना चाहते हैं, तो कृपया कृपया codereview.stackexchange.com
— kojiro

@ कोकोजी यह मेरे लिए काम नहीं कर रहा है, "बहुत
— भद्दी

जवाबों:


5

मैं वही करूंगा जो रेज़निक ने मूल रूप से सुझाया और फिर .formatउस पर कॉल किया:

def _fix_substitution_parms(raw_message: str) -> str:
    num_to_replace = raw_message.count("%s")
    python_format_string_message = raw_message.replace("%s", "{{{}}}")
    final_message = python_format_string_message.format(*range(num_to_replace))
    return final_message

यह तभी काम करेगा जब आपके पास %sपाठ में 2 हों ?
— चरिफ डीजेड

@CharifDZ और Aran-Fey - संपादन देखें। आप बस उन्हें हाथ से पहले
— दान

एक अच्छा समझौता लगता है ... पठनीय है, लेकिन बहुत फैंसी नहीं।
— घोस्टकट ने मोनिका सी।

8

re.subप्रत्येक तत्व के लिए एक बार प्रतिस्थापन को फिर से लागू करने और itertools.countक्रमिक रूप से संख्या प्राप्त करने के लिए एक लंबो फ़ंक्शन के साथ उपयोग करें :

import itertools
import re

s = "A %s B %s"

counter = itertools.count()
result = re.sub('%s', lambda x: f'{{{next(counter)}}}', s)
print(result)  # 'A {0} B {1}'

एक बार से अधिक इस ऑपरेशन को करने के लिए फ़ंक्शन में इसे लपेटने के लिए याद रखें, क्योंकि आपको ताज़ा करने की आवश्यकता होगी itertools.count।


अच्छा, भले ही मुझे यह थोड़ा "अस्पष्ट" लगता है; ;-)
— घोस्टकट ने मोनिका सी। को

@GhostCat यह अस्पष्ट नहीं है, काउंटर एक जनरेटर है जब आप कभी भी next(counter)इसे अगले मूल्य का उत्पादन कहते हैं , तो मैं हमेशा इस जनरेटर के बारे में भूल जाता हूं वास्तव में अच्छा जवाब
— चारिफ डीजेड

@GhostCat regex और कार्यात्मक प्रोग्रामिंग एक ही पंक्ति में: - मुझे लगता है कि "अस्पष्टता" इस बात पर निर्भर करती है कि आप इन उपकरणों के लिए कितने अभ्यस्त हैं।
— जफाकियोनी

3

मुझे लगता है कि काम करता है

rv.replace('%s','{{{}}}').format(*range(rv.count('%s')))


1
@GhostCat को एक-लाइनर्स द्वारा लुभाया नहीं जाना चाहिए, याद रखें कि लोगों को कोड बनाए रखना होगा
— Dan

1
@ मुझे पता है। लेकिन मैं कम कोड भी बनाए रखने के लिए कम कोड है।
— घोस्टकट ने मोनिका सी।

हालांकि यह कम नहीं है, यह सिर्फ डिबग करने के लिए कठिन है और पढ़ने के लिए भविष्य के देव के लिए कठिन है। यह उत्तर मेरे लिए समान होने के करीब है, इसमें एक ही फ़ंक्शन कॉल (विभाजन के लिए स्वैपिंग और शामिल होने के लिए स्वैपिंग) है लेकिन अगर एक मध्यवर्ती चरण में कोई समस्या है तो क्या होगा? आप इसे कैसे अलग करेंगे। और जो नए देव का तेज है यह समझने के लिए कि यह कोड से क्या करता है। मैं वास्तव में सलाह देता हूं कि आप इस तर्क को एक पंक्ति में न रखें।
— दान

1
एक अच्छा एक लाइनर नहीं। X.join(Y.split(Z))लेखन का सिर्फ एक जटिल तरीका है Y.replace(X, Z), और rangeकॉल को list(...)किसी में भी लपेटने की आवश्यकता नहीं है ।
— अरन-

1
@ हाँ, इसके बारे में खेद है, (केवल एक पंक्ति में अब) :)
— रेज़निक

1

re.subडायनामिक रिप्लेसमेंट के लिए उपयोग करना :

import re

text = "A %s B %s %s B %s"


def _fix_substitution_parms(raw_message):
    counter = 0
    def replace(_):
        nonlocal counter
        counter += 1
        return '{{{}}}'.format(counter - 1)
    return re.sub('%s', replace, raw_message)


print(_fix_substitution_parms(text))  # A {0} B {1} {2} B {3}

1
ध्यान रखें कि यह बच गए प्लेसहोल्डर्स ( %%s) के लिए जिम्मेदार नहीं है - यदि यह चिंता का विषय है, तो आप r'(?<!%)%s'इसके बजाय रेगेक्स का उपयोग कर सकते हैं ।
— अरन-फे

यदि आप बेवकूफ प्रश्न की अनुमति देते हैं: {{{}}}वास्तव में क्या हैं ?
— घोस्टकट ने मोनिका सी।

बचने के लिए तैयार स्ट्रिंग {हम \{हमेशा की तरह नहीं करते हैं {{।
— चारिफ़ डीजेड

1

जनरेटर का उपयोग करना:

def split_and_insert(mystring):
    parts = iter(mystring.split('%s'))
    yield next(parts)
    for n, part in enumerate(parts):
        yield f'{{{n}}}'
        yield part

new_string = ''.join(split_and_insert("A %s B %s"))

-4

क्या आपने .format के साथ प्रयास किया है?

string.format (0 = मान, 1 = मान)

इसलिए:

"A {0} B {1}".format(0=value, 1=value)


1
यह किसी को कैसे चालू करने %sमें मदद करता है {}?
— अरन-फे
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.