পাইথনের একটি স্ট্রিংয়ে একটি চরিত্র পরিবর্তন করা


385

স্ট্রিংয়ের চরিত্রটি প্রতিস্থাপনের জন্য পাইথনের সবচেয়ে সহজ উপায় কী?

উদাহরণ স্বরূপ:

text = "abcdefg";
text[1] = "Z";
           ^

উত্তর:


534

স্ট্রিংগুলি সংশোধন করবেন না।

তালিকা হিসাবে তাদের সাথে কাজ করুন; এগুলি কেবল যখন প্রয়োজন তখন স্ট্রিংগুলিতে পরিণত করুন।

>>> s = list("Hello zorld")
>>> s
['H', 'e', 'l', 'l', 'o', ' ', 'z', 'o', 'r', 'l', 'd']
>>> s[6] = 'W'
>>> s
['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd']
>>> "".join(s)
'Hello World'

পাইথনের স্ট্রিং অপরিবর্তনীয় (যেমন সেগুলি সংশোধন করা যায় না)। এর অনেক কারণ রয়েছে। আপনার কোনও পছন্দ না হওয়া পর্যন্ত তালিকাগুলি ব্যবহার করুন, কেবল তারপরে সেগুলিতে স্ট্রিংয়ে পরিণত করুন।


4
যারা গতি / দক্ষতার সন্ধান করছেন, এটি পড়ুন
আনিসআহমেড777

4
"স্ট্রিংগুলি সংশোধন করবেন না।" কেন
হ্যাকসোই

2
"তৈরি করুন -> পরিবর্তন করুন-> সিরিয়ালাইজ-> অ্যাসাইনমেন্ট-> ফ্রি" এস এর চেয়ে আরও কার্যকর - []] = 'ডাব্লু'? হুঁ ... কারণগুলির "অনেক" সত্ত্বেও অন্যান্য ভাষাগুলি কেন এটি অনুমতি দেয়? আকর্ষণীয় কীভাবে একটি অদ্ভুত নকশা রক্ষা করা যেতে পারে (ভালবাসার জন্য আমি মনে করি)। পাইথন কোরটিতে একটি ফাংশন এমআইডি (স্ট্রওয়ার, সূচক, নিউচার) যুক্ত করার পরামর্শ দিচ্ছেন না কেন যা পুরো স্ট্রিংয়ের সাথে অবিচ্ছিন্নভাবে বাইট বদলানোর পরিবর্তে চর মেমরি অবস্থানটি অ্যাক্সেস করে?
অস্কার

@ হ্যাকসোই, @scar, কারণটি বেশ সহজ: অনুলিপি-অনুলিপি বাস্তবায়নের জন্য পয়েন্টারগুলি অতিক্রম করার সময় পুনরায় গণনা করার দরকার নেই, বা কেউ যদি সেই স্ট্রিংটি সংশোধন করতে চায় তবে পুরো স্ট্রিংটি সম্পূর্ণ অনুলিপি করে তোলে - এটি জেনেরিকের গতি বৃদ্ধির দিকে পরিচালিত করে ব্যবহার করুন। MIDটুকরো টুকরো করার মতো জিনিসের দরকার নেই :s[:index] + c + s[index+1:]
মাল্টিস্কিল

1
@scar বোবা ভাষায় আমার অর্থ হ'ল তারা ইউনিকোডের সাথে লেনদেন করবেন না যদি আপনি তাদের স্পষ্টভাবে না বলে থাকেন। অবশ্যই আপনি সি তে ইউনিকোড সক্ষম অ্যাপ্লিকেশন লিখতে পারেন তবে আপনাকে সর্বদা এটির যত্ন নিতে হবে এবং সমস্যা এড়াতে এটি স্পষ্টভাবে পরীক্ষা করা দরকার। সবকিছুই যন্ত্র-ভিত্তিক। পাইথন শেখার আগে আমি পিএইচপি এর সাথে কাজ করেছি এবং ভাষাটি মোটামুটি গণ্ডগোল। দ্রুত সিপিইউতে আপনার নোট সম্পর্কিত আমি সম্পূর্ণ আপনার সাথে আছি। তবে সেই সমস্যার একটি অংশ অকাল অপটিমাইজেশনের জনপ্রিয় অস্বীকৃতি, যা পথে প্রচুর সিপিইউ চক্র ফাঁস করে দোভাষী এবং গ্রন্থাগারগুলিকে ধীরে ধীরে নিয়ে যায়।
বাচসৌ

202

দ্রুততম পদ্ধতি?

তিনটি উপায় আছে। গতি সন্ধানীদের জন্য আমি 'পদ্ধতি 2' এর সুপারিশ করছি

পদ্ধতি 1

এই উত্তর দিয়ে দেওয়া

text = 'abcdefg'
new = list(text)
new[6] = 'W'
''.join(new)

'পদ্ধতি 2' এর তুলনায় যা বেশ ধীর

timeit.timeit("text = 'abcdefg'; s = list(text); s[6] = 'W'; ''.join(s)", number=1000000)
1.0411581993103027

পদ্ধতি 2 (দ্রুত পদ্ধতি)

এই উত্তর দিয়ে দেওয়া

text = 'abcdefg'
text = text[:1] + 'Z' + text[2:]

যা অনেক দ্রুত:

timeit.timeit("text = 'abcdefg'; text = text[:1] + 'Z' + text[2:]", number=1000000)
0.34651994705200195

পদ্ধতি 3:

বাইট অ্যারে:

timeit.timeit("text = 'abcdefg'; s = bytearray(text); s[1] = 'Z'; str(s)", number=1000000)
1.0387420654296875

1
এটি কীভাবে বাইটারি পদ্ধতিতে ভাড়া নিয়ে যায় তা দেখতে আকর্ষণীয় হবে।
চমত্কার

1
ভাল পরামর্শ। বাইটারি পদ্ধতিটিও ধীর: দ্রুততমের timeit.timeit("text = 'abcdefg'; s = bytearray(text); s[1] = 'Z'; str(s)", number=1000000)চেয়ে দ্বিগুণ।
মেহেদী নেলেন

2
পরীক্ষাগুলির প্রশংসা করুন, যা পাইথনের স্ট্রিংগুলি কীভাবে পরিচালনা করতে হবে সে সম্পর্কে আমাকে পুনর্বিবেচনা দেয়।
বর্ণালী

1
খুশী হলাম। পদ্ধতিটি 3 টি অন্তর্ভুক্ত করার জন্য দয়া করে উত্তরটি সম্পাদনা করুন (বাইটারি)।
আনিসআহমেড 777

1
এটি লক্ষ করা উচিত যে এখানে বেশিরভাগ সময় রূপান্তরগুলিতে ব্যয় করা হয় ... (স্ট্রিং -> বাইট অ্যারে)। আপনার যদি স্ট্রিংটিতে অনেকগুলি সম্পাদনা করতে হয়, তবে বাইট অ্যারে পদ্ধতিটি আরও দ্রুত হবে।
ইয়ান সুডবেরি


37

পাইথন স্ট্রিংগুলি পরিবর্তনযোগ্য নয়, আপনি একটি অনুলিপি তৈরি করে এগুলি পরিবর্তন করেন।
আপনি যা চান তা করার সহজতম উপায় সম্ভবত:

text = "Z" + text[1:]

text[1:]রিটার্ন স্ট্রিং textশেষ অবস্থানে 1 থেকে, অবস্থান 0 থেকে গণনা তাই '1' দ্বিতীয় চরিত্র।

সম্পাদনা: স্ট্রিংয়ের যে কোনও অংশের জন্য আপনি একই স্ট্রিং স্লাইসিং কৌশলটি ব্যবহার করতে পারেন

text = text[:1] + "Z" + text[2:]

বা যদি চিঠিটি কেবল একবার উপস্থিত হয় আপনি নীচে প্রস্তাবিত কৌশলটি সন্ধান এবং প্রতিস্থাপন করতে পারেন


আমি ২ য় চরিত্র, IE। স্থান 1 নম্বর চরিত্র (1 ম চরিত্র হিসাবে প্রয়োগ করা হয়, সংখ্যা 0)
কোস্টিয়া

পাঠ্য [0] + "জেড" + পাঠ্য [2:]
ডাব্লুবিজি

13

পাইথন ২.6 এবং অজগর 3 দিয়ে শুরু করে আপনি বাইটায়ারগুলি ব্যবহার করতে পারেন যা পরিবর্তনীয় (স্ট্রিংয়ের বিপরীতে উপাদান অনুসারে পরিবর্তিত হতে পারে):

s = "abcdefg"
b_s = bytearray(s)
b_s[1] = "Z"
s = str(b_s)
print s
aZcdefg

সম্পাদনা: এস আর এস পরিবর্তন করা হয়েছে

সম্পাদনা 2: দ্বি-বিট অ্যালকেমিস্ট মন্তব্যে উল্লিখিত হিসাবে, এই কোডটি ইউনিকোড দিয়ে কাজ করে না।


এই উত্তরটি ভুল। একটি জিনিস জন্য, এটি হওয়া উচিত bytearray(s), না bytearray(str)। অন্য জন্য, এই হবে উত্পাদন: TypeError: string argument without an encoding। আপনি যদি কোনও এনকোডিং নির্দিষ্ট করেন তবে আপনি পাবেন TypeError: an integer is required। পাইথন 3 বা পাইথন 2 এর ইউনিকোডের সাথে। আপনি যদি পাইথন 2 এ এটি সংশোধন করেন (সংশোধন করা দ্বিতীয় লাইনের সাহায্যে), এটি অ-এসসিআইআই অক্ষরের জন্য কাজ করবে না কারণ সেগুলি কেবল একটি বাইট নাও হতে পারে। এটি দিয়ে চেষ্টা করুন s = 'Héllo'এবং আপনি পাবেন 'He\xa9llo'
টু-বিট অ্যালকেমিস্ট

আমি পাইথন ২..9.৯ এ আবার চেষ্টা করেছি। আপনার উল্লিখিত ত্রুটিটি আমি আবার জেনারেট করতে পারিনি (TypeError: এনকোডিং ছাড়াই স্ট্রিং আর্গুমেন্ট)।
মাহমুদ

আপনি যদি ইউনিকোড ব্যবহার করছেন তবেই সেই ত্রুটিটি প্রযোজ্য। ব্যবহার করে দেখুন s = u'abcdefg'
টু-বিট অ্যালকেমিস্ট

4
এটা করো না. এই পদ্ধতিটি স্ট্রিং এনকোডিংগুলির সম্পূর্ণ ধারণাটিকে উপেক্ষা করে, যার অর্থ এটি কেবলমাত্র ASCII অক্ষরগুলিতে কাজ করার জন্য ঘটে। এই দিন এবং যুগে আপনি ASCII ধরে নিতে পারবেন না, এমনকি আপনি যদি কোনও ইংরেজী স্পিকারের দেশে ইংরেজী স্পিকার হন। পাইথন 3 এর বৃহত্তম পিছনে অসঙ্গতি, এবং আমার মতে সবচেয়ে গুরুত্বপূর্ণ, এই পুরো বাইট = স্ট্রিংয়ের মিথ্যা সমতুল্যতা ঠিক করা। ফিরিয়ে আনবেন না।
আদম

5

অন্যান্য লোকেরা যেমন বলেছে, সাধারণত পাইথনের স্ট্রিংগুলি অনির্বচনীয় বলে মনে করা হয়।

তবে, আপনি যদি পাইথন ব্যবহার করেন, পাইথন.আর. তে প্রয়োগকরণ, মেমরির স্ট্রিং কাঠামো পরিবর্তন করতে সিটিপিস ব্যবহার করা সম্ভব।

এখানে একটি উদাহরণ যেখানে আমি কৌশলটি কোনও স্ট্রিং সাফ করার জন্য ব্যবহার করি।

পাইথনে সংবেদনশীল হিসাবে ডেটা চিহ্নিত করুন

আমি সম্পূর্ণতার জন্য এটি উল্লেখ করেছি, এবং এটি হ্যাকিশ হওয়ার কারণে এটিই আপনার শেষ অবলম্বন হওয়া উচিত।


6
শেষ অবলম্বন? আপনি যদি কখনও এটি করেন তবে হঠাৎ আপনি মন্দ হিসাবে চিহ্নিত হন!
ক্রিস মরগান

@ ক্রিসমর্গান যদি আপনার স্ট্রিংটিতে একটি পাসওয়ার্ড থাকে তবে এটিকে s = '' দিয়ে সাফ করা যথেষ্ট নয় কারণ পাসওয়ার্ডটি মেমোরিতে এখনও কোথাও লেখা আছে। এটি টাইপগুলির মাধ্যমে সাফ করার একমাত্র উপায়।
ক্যাবু

1
@Cabu আমি চাই না অধীনে কোনো পরিস্থিতিতে কোড যে করেনি গ্রহণ। যদি আপনার ডেটা সংবেদনশীল হয় এবং আপনি এই জাতীয় সুরক্ষা সম্পর্কে যত্নশীল হন তবে strএটি আপনার পক্ষে সঠিক ধরণের নয়। শুধু এটি ব্যবহার করবেন না। bytearrayপরিবর্তে কিছু ব্যবহার করুন । (আরও ভাল, এটি এমন কোনও মোড়কে মুছুন যা আপনাকে এটি অস্বচ্ছ ডেটা হিসাবে কম-বেশি চিকিত্সা করতে দেয় যাতে দুর্ঘটনা থেকে রক্ষা পেতে আপনি সত্যই এটি থেকে কোনও পুনরুদ্ধার করতে পারবেন নাstr that এর জন্য কোনও গ্রন্থাগার থাকতে পারে No কোনও ধারণা নেই))
ক্রিস মরগান

4

এই কোডটি আমার নয়। আমি যে সাইট ফর্মটি নিয়েছিলাম তা মনে করতে পারি না। আকর্ষণীয়ভাবে, আপনি এটি ব্যবহার করতে পারেন একটি চরিত্র বা আরও একাধিক অক্ষরের সাথে প্রতিস্থাপন করতে। যদিও এই উত্তরটি খুব দেরিতে হয়েছে, আমার মতো নবীনদের (যে কোনও সময়) এটি কার্যকর হতে পারে।

পাঠ্য ফাংশন পরিবর্তন করুন।

mytext = 'Hello Zorld'
mytext = mytext.replace('Z', 'W')
print mytext,

11
এটি প্রশ্নের উত্তর দেয় না। এটি মোটেই পছন্দসই ছিল না।
ক্রিস মরগান

2
আপনি কেবলমাত্র প্রথমটি প্রতিস্থাপন করতে চাইলে এই কোডটি খারাপ lmytext = mytext.replace('l', 'W')->HeWWo Zorld
ওকার

আপনি যদি সার্জিকভাবে কেবলমাত্র 1 টি চরিত্র (যা আমি আছি) প্রতিস্থাপন করতে চাইছেন তবে এটি বিলটি পুরোপুরি ফিট করে। ধন্যবাদ!
ProfVersaggi

পছন্দ করুন ওকারের উপরের মন্তব্যটি দেখুন।
টু-বিট অ্যালকেমিস্ট

3
@ ওকার আপনি যদি কেবলমাত্র প্রথম অক্ষরটি প্রতিস্থাপন করতে চান তবে আপনি ব্যবহার করতে পারেন mytext = mytext.replace('l', 'W',1)দস্তাবেজের লিঙ্ক
অ্যালেক্স

2

আসলে, স্ট্রিং সহ, আপনি এর মতো কিছু করতে পারেন:

oldStr = 'Hello World!'    
newStr = ''

for i in oldStr:  
    if 'a' < i < 'z':    
        newStr += chr(ord(i)-32)     
    else:      
        newStr += i
print(newStr)

'HELLO WORLD!'

মূলত, আমি একটি নতুন স্ট্রিংয়ের সাথে "+" স্ট্রিংগুলি "যুক্ত করছি"।


4
এটি খুব ধীর হতে চলেছে কারণ প্রতিটি সংক্ষেপে একটি নতুন স্ট্রিং অবজেক্ট তৈরি করতে হয়, যেহেতু তারা অপরিবর্তনীয়, যা এই প্রশ্নটি সম্পর্কে।
টু-বিট অ্যালকেমিস্ট

0

যদি আপনার বিশ্ব 100% হয় ascii/utf-8(প্রচুর ব্যবহারের কেস সেই বাক্সে ফিট করে):

b = bytearray(s, 'utf-8')
# process - e.g., lowercasing: 
#    b[0] = b[i+1] - 32
s = str(b, 'utf-8')

অজগর 3.7.3


0

আমি একটি স্ট্রিংয়ে একটি চরিত্র পরিবর্তন করার অন্য উপায় যুক্ত করতে চাই।

>>> text = '~~~~~~~~~~~'
>>> text = text[:1] + (text[1:].replace(text[0], '+', 1))
'~+~~~~~~~~~'

স্ট্রিংটিকে তালিকায় পরিণত করা এবং ith মান প্রতিস্থাপনের সাথে আবার যুক্ত হওয়ার সাথে তুলনা করা কত দ্রুত হয় ?.

তালিকা পদ্ধতির

>>> timeit.timeit("text = '~~~~~~~~~~~'; s = list(text); s[1] = '+'; ''.join(s)", number=1000000)
0.8268570480013295

আমার সমাধান

>>> timeit.timeit("text = '~~~~~~~~~~~'; text=text[:1] + (text[1:].replace(text[0], '+', 1))", number=1000000)
0.588400217000526
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.