स्ट्रिंग में सभी वर्णों को प्रतिस्थापित करने के लिए मुझे खाली स्ट्रिंग क्यों बनाना है?

मैं एक ROT13 समारोह लिख रहा हूं, और मुझे समझ में नहीं आ रहा है कि निम्नलिखित क्यों काम नहीं करते हैं:

def ROT(string):
    # y = 0
    for char in string:
        x = ord(char)
        if 97 <= x < 110 or 65 <= x < 78:
            # string[y]=char.replace(char, chr(x+13))
            char=char.replace(char, chr(x+13))
            print(char)
            # y+=1
        elif x >= 110 or 78 <= x < 91:
            # string[y]=char.replace(char, chr(x-13))
            char=char.replace(char, chr(x-13))
            print(char)
            # y+=1
    return string

string = ROT('Hello, lorem ipsum dolor sit amet')
print(string)

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

3
आपको क्या सटीक त्रुटि मिल रही है?
जोड़ा लेखक thumbtackthief, स्रोत

4 उत्तर

आपके कोड में समस्या यह है कि आप मूल स्ट्रिंग में हेरफेर नहीं कर रहे हैं। आप केवल अस्थायी चर char को बदल रहे हैं और मूल स्ट्रिंग में नहीं। चूंकि स्ट्रिंग पाइथन में अपरिवर्तनीय हैं, इसलिए आप एक नई स्ट्रिंग का उपयोग करने और मूल स्ट्रिंग को बदलने की बजाय कोशिश कर सकते हैं, आप केवल वर्णों को नई स्ट्रिंग में जोड़ सकते हैं। पसंद:

modified_string = ""
for char in string:
     #whatever condition
     modified_string += #value to be added
4
जोड़ा
यदि प्रदर्शन एक चिंता है, तो यह पाइथन में से बचने के लिए एक मुहावरे है क्योंकि इसमें समयबद्ध जटिलता है।
जोड़ा लेखक mgilson, स्रोत
एक कोड में modified_string + = ...
जोड़ा लेखक mgilson, स्रोत
@AwinwinMurugesh - मैंने नीचे एक और जवाब पोस्ट किया। आप एक bytearray का उपयोग कर सकते हैं जो एक परिवर्तनीय सूची-स्ट्रिंग हाइब्रिड की तरह कम या ज्यादा व्यवहार करता है। या, जैसा कि मैं अपने उत्तर में काम करता हूं, आप string.translate का उपयोग कर सकते हैं।
जोड़ा लेखक mgilson, स्रोत
@AswinMurugesh - हाँ, string.translate सबसे लोकप्रिय फ़ंक्शन नहीं है। लेकिन विचार वास्तव में मुश्किल नहीं है। आप 2 स्ट्रिंग बनाते हैं - आप स्ट्रिंग में वर्णों को tochr से संबंधित चरित्र तक tochr में अनुवाद करते हैं ...
जोड़ा लेखक mgilson, स्रोत
आप पाइथन में ऐसी चीजें नहीं कर सकते हैं .. temp = string + char हो सकता है .. स्थिति की जांच करें .. अगर यह संतुष्ट हो, तो string = temp असाइन करें
जोड़ा लेखक Aswin Murugesh, स्रोत
@ मिगिलसन: कौन सा?
जोड़ा लेखक Aswin Murugesh, स्रोत
@mgilson कोई अन्य इष्टतम तरीका?
जोड़ा लेखक Aswin Murugesh, स्रोत
@mgilson: यह अच्छा है .. लेकिन शुरुआत करने के लिए शुरुआत करने के लिए बहुत मुश्किल है ..
जोड़ा लेखक Aswin Murugesh, स्रोत
आह! मुझे समझ आ गया। अगर मैंने स्ट्रिंग = स्ट्रिंग + char जैसे कुछ किया है तो मेरे कथन में यह काम करेगा?
जोड़ा लेखक ekrah, स्रोत

आप मूल स्ट्रिंग लौट रहे थे, कोशिश करें

def ROT(string):
#   y = 0
    result = ""
    for char in string:
        x = ord(char)
        if 97 <= x < 110 or 65 <= x < 78:
#           string[y]=char.replace(char, chr(x+13))
            char=char.replace(char, chr(x+13))
            result = result + char
            print(char)
            continue
#           y+=1
        elif x >= 110 or 78 <= x < 91:
#           string[y]=char.replace(char, chr(x-13))
            char=char.replace(char, chr(x-13))
            print(char)
            result = result + char
            continue
#           y+=1
        result = result + char
    return result

string = ROT('Hello, lorem ipsum dolor sit amet')
print(string)
2
जोड़ा

पायथन में स्ट्रिंग्स अपरिवर्तनीय हैं।

2
जोड़ा
यह सवाल इहोहो का वास्तविक जवाब है: पी
जोड़ा लेखक Joran Beasley, स्रोत

अन्य ने पहले से ही मुख्य समस्या को संबोधित कर लिया है - तार अपरिवर्तनीय हैं, इसलिए आप पुनरावृत्ति करते समय केवल एक ही चरित्र को स्विच नहीं कर सकते हैं। आप इसके बजाय bytearray का उपयोग कर सकते हैं, लेकिन ...

एफडब्ल्यूआईडब्ल्यू, यह string.translate के लिए एक अच्छा उम्मीदवार है:

>>> import string
>>> fromchr = ''.join(chr(x) for x in range(97, 110) + range(65, 78))
>>> tochr = ''.join(chr(x+13) for x in range(97, 110) + range(65, 78))
>>> fromchr += ''.join(chr(x) for x in range(110, 256) + range(78, 91))
>>> tochr += ''.join(chr(x-13) for x in range(110, 256) + range(78, 91))
>>> trans = string.maketrans(fromchr, tochr)
>>> 'Hello, lorem ipsum dolor sit amet'.translate(trans)
'Uryyb, yberz vcfhz qbybe fvg nzrg'

यहां बड़ी बात यह है कि अनुवाद तालिका बनाना 1-बार की लागत है। अनुवाद तालिका बनाई जाने के बाद, आप इसे जितनी बार चाहें उतनी बार उपयोग कर सकते हैं। आपका अनुवाद ऑप्टिमाइज्ड सी कोड में ~ ओ (एन) समय में होगा, इसलिए मुझे आश्चर्य होगा कि अगर आप एक कार्यान्वयन प्राप्त कर सकते हैं जो बहुत तेज़ (या वास्तव में सरल) है।

इस तरह से भी अंतर्निहित बिल्टिन 'rot13' कोडेक को धड़कता है:

def rot13a(s):
  return s.encode('rot13')

import string
fromchr = ''.join([chr(x) for x in range(97, 110) + range(65, 78)])
tochr = ''.join([chr(x+13) for x in range(97, 110) + range(65, 78)])
fromchr += ''.join(chr(x) for x in range(110, 256) + range(78, 91))
tochr += ''.join(chr(x-13) for x in range(110, 256) + range(78, 91))
trans = string.maketrans(fromchr, tochr)
def rot13b(s):
  return s.translate(trans)

import timeit
test_string = 'Hello, lorem ipsum dolor sit amet'
print rot13a(test_string) == rot13b(test_string)
print timeit.timeit("rot13a(test_string)", "from __main__ import test_string, rot13a")
print timeit.timeit("rot13b(test_string)", "from __main__ import test_string, rot13b")

(मेरे परिणाम):

True
1.52055001259  # rot13a
0.21444106102  # rot13b

ध्यान दें कि यह python2.x कोड है। Python3.x में, आप केवल उस श्रेणी को नहीं जोड़ सकते हैं क्योंकि range अब सूची ऑब्जेक्ट नहीं देता है। लेकिन, उम्मीद है कि विचार पर्याप्त स्पष्ट है ...

1
जोड़ा
हां अब मैं इसे स्पष्ट रूप से प्राप्त करता हूं .. अच्छा काम .. इसे पहली बार देख रहा हूं ..
जोड़ा लेखक Aswin Murugesh, स्रोत