পাইথনের স্ট্রিং কি পরিবর্তনযোগ্য নয়? তাহলে কেন একটি + "" + বি কাজ করে?


109

আমার বোঝাপড়াটি ছিল যে পাইথনের স্ট্রিংগুলি পরিবর্তনযোগ্য নয়।

আমি নিম্নলিখিত কোড চেষ্টা করেছিলাম:

a = "Dog"
b = "eats"
c = "treats"

print a, b, c
# Dog eats treats

print a + " " + b + " " + c
# Dog eats treats

print a
# Dog

a = a + " " + b + " " + c
print a
# Dog eats treats
# !!!

পাইথন অ্যাসাইনমেন্ট আটকাতে হবে না? আমি সম্ভবত কিছু মিস করছি।

কোন ধারণা?


55
স্ট্রিং নিজেই পরিবর্তনযোগ্য তবে লেবেল পরিবর্তন হতে পারে।
মিচ

6
বিদ্যমান ভেরিয়েবলকে নতুন মান নির্ধারণ করা পুরোপুরি বৈধ। পাইথনের ধ্রুবক নেই। এটি ডেটা টাইপের পরিবর্তন থেকে পৃথক।
ফেলিক্স ক্লিং

14
আপনি id()ফাংশনটি একবার দেখে নিতে পারেন । aঅ্যাসাইনমেন্টের আগে এবং পরে আলাদা আইডি থাকবে যা ইঙ্গিত করে যে এটি বিভিন্ন বস্তুর দিকে নির্দেশ করছে। কোড সহ একইভাবে মত b = aআপনি যে পাবেন aএবং bএকই আইডি থাকবে, যা নির্দেশ তারা একই বস্তুর উল্লেখ করছি।
ডিআরএইচ


ডেলানানের লিঙ্কটি হ'ল আমি যা উল্লেখ করছি।
মিচ

উত্তর:


180

প্রথমে a"কুকুর" স্ট্রিংয়ের দিকে ইঙ্গিত করলেন। তারপরে আপনি ভেরিয়েবলটিকে aএকটি নতুন স্ট্রিং "ডগ ইট ট্রিটস" এ নির্দেশ করুন। আপনি আসলে "কুকুর" স্ট্রিংটি পরিবর্তন করতে পারেন নি। স্ট্রিংগুলি অপরিবর্তনীয়, ভেরিয়েবলগুলি যা চায় তার দিকে নির্দেশ করতে পারে।


34
X = 'abc' এর মতো কিছু চেষ্টা করা আরও দৃinc়প্রত্যয়ী; x [1] পাইথন
repl-

1
আপনি যদি অভ্যন্তরীণ কিছুটা আরও বুঝতে চান তবে আমার উত্তর দেখুন। stackoverflow.com/a/40702094/117471
ব্রুনো Bronosky

53

স্ট্রিং অবজেক্টগুলি নিজেরাই অপরিবর্তনীয়।

পরিবর্তনশীল, aযা স্ট্রিংকে নির্দেশ করে, পরিবর্তনীয়।

বিবেচনা:

a = "Foo"
# a now points to "Foo"
b = a
# b points to the same "Foo" that a points to
a = a + a
# a points to the new string "FooFoo", but b still points to the old "Foo"

print a
print b
# Outputs:

# FooFoo
# Foo

# Observe that b hasn't changed, even though a has.

@ জেসন তালিকাগুলির সাথে একই ধরণের অপারেশনগুলি চেষ্টা করুন (যা পারস্পরিক পরিবর্তনযোগ্য) পার্থক্যটি দেখতে a.append (3) a = a + "Foo" এর সাথে
সামঞ্জস্য রয়েছে

1
@jimifiki a.append(3) নয় হিসাবে একই a = a + 3। এটি এমনকি নয় a += 3(স্থান সংযোজন সমান .extend, এর সাথে নয় .append)।

@ ডেলান এবং তাই, কি? স্ট্রিং এবং তালিকাগুলি আলাদাভাবে আচরণ করে তা দেখানোর জন্য আপনি ধরে নিতে পারেন যে a = a + "ফু" a.append (কিছু) হিসাবে একই। যে কোনও ক্ষেত্রে এটি এক রকম নয়। একথাও ঠিক যে। আপনি কি a.append (কিছু) এর পরিবর্তে a.extend ([কিছু]) পড়ে বেশি খুশি হন? আমি এই প্রসঙ্গে এত বড় পার্থক্য দেখছি না। তবে সম্ভবত আমি কিছু মিস করছি। থ্রুথ প্রসঙ্গে নির্ভর করে
জিমিফিকি

@ জিমিফিকি: আপনি কী সম্পর্কে কথা বলছেন? +তালিকাগুলি এবং স্ট্রিংগুলির জন্য একই আচরণ করে - এটি একটি নতুন অনুলিপি তৈরি করে এবং অপরেন্ডকে মিউটেশন না করে সংহত করে।

6
এই সমস্ত থেকে দূরে নেওয়ার সত্যিকারের গুরুত্বপূর্ণ বিষয়টি হচ্ছে স্ট্রিংগুলির কোনও append ক্রিয়াকলাপ নেই কারণ সেগুলি পরিবর্তনযোগ্য।
লিলি চুং

46

ভ্যারিয়েবল এ "কুকুর" অবজেক্টটির দিকে নির্দেশ করছে। পাইথনের পরিবর্তনশীলটিকে ট্যাগ হিসাবে ভাবা ভাল। আপনি ট্যাগটি বিভিন্ন অবজেক্টে সরাতে পারেন যা আপনি যখন করেছিলেন তখনই a = "dog"তা করেছিলেন a = "dog eats treats"

যাইহোক, অপরিবর্তনীয়তা বস্তুটিকে বোঝায়, ট্যাগ নয়।


আপনি চেষ্টা যদি a[1] = 'z'করতে "dog"বা "dzg", আপনি ভুল পান হবে:

TypeError: 'str' object does not support item assignment" 

স্ট্রিং আইটেম অ্যাসাইনমেন্ট সমর্থন করে না, এইভাবে তারা অপরিবর্তনীয়।


19

কিছু তখনই পরিবর্তনযোগ্য হয় যখন আমরা মেমরির অবস্থানটি পরিবর্তন না করে মেমরির অবস্থানটিতে রাখা মানগুলি পরিবর্তন করতে সক্ষম হয়েছি।

কৌশলটি হ'ল: যদি আপনি দেখতে পান যে পরিবর্তনের আগে এবং পরে মেমরির অবস্থান একই হয় তবে এটি পরিবর্তনীয়।

উদাহরণস্বরূপ, তালিকাটি পরিবর্তনযোগ্য। কিভাবে?

>> a = ['hello']
>> id(a)
139767295067632

# Now let's modify
#1
>> a[0] = "hello new"
>> a
['hello new']
Now that we have changed "a", let's see the location of a
>> id(a)
139767295067632
so it is the same as before. So we mutated a. So list is mutable.

একটি স্ট্রিং অপরিবর্তনীয়। আমরা কীভাবে এটি প্রমাণ করব?

> a = "hello"
> a[0]
'h'
# Now let's modify it
> a[0] = 'n'
----------------------------------------------------------------------

আমরা পেতে

TypeError: 'str' অবজেক্ট আইটেম অ্যাসাইনমেন্ট সমর্থন করে না

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

আপনার পুনরায় নিয়োগের ক্ষেত্রে, আপনি ভেরিয়েবলটি একটি নতুন অবস্থানে দেখানোর জন্য পরিবর্তন করেন। এখানে আপনি স্ট্রিংটি পরিবর্তন করতে পারেন নি, তবে নিজেই পরিবর্তনশীল পরিবর্তন করতে পারেন। নিম্নলিখিত আপনি কি করছেন।

>> a = "hello"
>> id(a)
139767308749440
>> a ="world"
>> id(a)
139767293625808

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


11

একটি ভেরিয়েবল কেবল একটি বস্তুর দিকে নির্দেশ করে একটি লেবেল। অবজেক্টটি অপরিবর্তনীয় তবে আপনি চাইলে লেবেলটিকে একেবারে অন্যরকম বস্তুতে পরিণত করতে পারেন।


8

বিবেচনা:

>>> a='asdf'
>>> a.__repr__
<method-wrapper '__repr__' of str object at 0x1091aab90>
>>> a='asdf'
>>> a.__repr__
<method-wrapper '__repr__' of str object at 0x1091aab90>
>>> a='qwer'
>>> a.__repr__
<method-wrapper '__repr__' of str object at 0x109198490>

লক্ষ্য করুন যে আমি যখন একই ভেরিয়েবলটিতে দু'বার একই মান সংরক্ষণ করি তখন হেক্স মেমরির অবস্থান পরিবর্তন হয় নি। আমি পরিবর্তিত হয়েছি যখন আমি একটি আলাদা মান সঞ্চয় করি। স্ট্রিং অপরিবর্তনীয়। উদ্যোগীকরণের কারণে নয়, আপনি স্মৃতিতে একটি নতুন অবজেক্ট তৈরির পারফরম্যান্স জরিমানা প্রদানের কারণে। ভেরিয়েবলটি কেবল aসেই মেমরি ঠিকানার দিকে ইঙ্গিত করে একটি লেবেল। এটি কোনও কিছুর দিকে নির্দেশ করতে পরিবর্তন করা যেতে পারে।


7

a = a + " " + b + " " + cপয়েন্টারগুলির ভিত্তিতে বিবৃতিটি ভেঙে ফেলা যায়।

a + " "বলে আমাকে কোন aপয়েন্ট দিন, যা পরিবর্তন করা যায় না, এবং " "আমার বর্তমান কার্যস্থলে যোগ করুন ।

স্মৃতি:

working_set = "Dog "
a = "Dog" 
b = "eats"
c = "treats"

+ bবলে আমাকে কোন bপয়েন্ট দিন, যা পরিবর্তন করা যায় না, এবং এটি বর্তমান কার্যকারী সেটগুলিতে যুক্ত করুন।

স্মৃতি:

working_set = "Dog eats"
a = "Dog" 
b = "eats"
c = "treats"

+ " " + c" "বর্তমান সেট যোগ করুন । তারপরে আমাকে কোন cপয়েন্টগুলি দিন, যা পরিবর্তন করা যায় না এবং এটি বর্তমান কার্যকারী সেটগুলিতে যুক্ত করুন। স্মৃতি:

working_set = "Dog eats treats"
a = "Dog" 
b = "eats"
c = "treats"

অবশেষে, a =বলেছে যে আমার পয়েন্টারটি ফলাফলের সেটটিতে নির্দেশ করবে।

স্মৃতি:

a = "Dog eats treats"
b = "eats"
c = "treats"

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


6
l = [1,2,3]
print id(l)
l.append(4)
print id(l) #object l is the same

a = "dog"
print id(a)
a = "cat"
print id(a) #object a is a new object, previous one is deleted

5

ডেটা এবং এটির সাথে যুক্ত লেবেলের মধ্যে পার্থক্য রয়েছে। যেমন আপনি যখন করবেন

a = "dog"

ডেটা "dog"তৈরি করা হয় এবং লেবেলের নীচে রাখা হয় a। লেবেল পরিবর্তন করতে পারে তবে যা মেমরিতে থাকে তা তা করতে পারে না। আপনার করার "dog"পরেও ডেটা মেমরির মধ্যে থাকবে (যতক্ষণ না আবর্জনা সংগ্রহকারী এটি মুছে না ফেলে)

a = "cat"

আপনার প্রোগ্রামে aএখন ^ পয়েন্ট ^ "cat"কিন্তু স্ট্রিং "dog"পরিবর্তন হয়নি।


3

পাইথনের স্ট্রিং অবিচ্ছেদ্য। তবে, aস্ট্রিং নয়: এটি স্ট্রিংয়ের মান সহ একটি পরিবর্তনশীল vari আপনি স্ট্রিংটি পরিবর্তন করতে পারবেন না, তবে ভেরিয়েবলের মানটি একটি নতুন স্ট্রিংয়ে পরিবর্তন করতে পারবেন।


2

ভেরিয়েবলগুলি যে কোনও জায়গাতে ইঙ্গিত করতে পারে .. আপনি নিম্নলিখিতটি করলে একটি ত্রুটি নিক্ষেপ করা হবে:

a = "dog"
print a                   #dog
a[1] = "g"                #ERROR!!!!!! STRINGS ARE IMMUTABLE

2

পাইথন স্ট্রিং অবজেক্টগুলি অপরিবর্তনীয়। উদাহরণ:

>>> a = 'tanim'
>>> 'Address of a is:{}'.format(id(a))
'Address of a is:64281536'
>>> a = 'ahmed'
>>> 'Address of a is:{}'.format(id(a))
'Address of a is:64281600'

এই উদাহরণে আমরা দেখতে পাচ্ছি যে যখন আমরা একটিতে বিভিন্ন মান নির্ধারণ করি এটি পরিবর্তন হয় না A একটি নতুন অবজেক্ট তৈরি হয়।
এবং এটি সংশোধন করা যায় না। উদাহরণ:

  >>> a[0] = 'c'
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    **TypeError**: 'str' object does not support item assignment

একটি ত্রুটি ঘটে।


2

'পরিবর্তনযোগ্য' এর অর্থ আমরা স্ট্রিংয়ের সামগ্রী পরিবর্তন করতে পারি, 'স্থাবর' এর অর্থ আমরা কোনও অতিরিক্ত স্ট্রিং যুক্ত করতে পারি না।

ছবির প্রমাণের জন্য ক্লিক করুন


1

>>> a = 'dogs'

>>> a.replace('dogs', 'dogs eat treats')

'dogs eat treats'

>>> print a

'dogs'

অপরিবর্তনীয়, তাই না ?!

পরিবর্তনশীল পরিবর্তনের অংশটি ইতিমধ্যে আলোচনা করা হয়েছে।


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

1

আপনার উদাহরণের সাথে এই সংযোজনটি বিবেচনা করুন

 a = "Dog"
 b = "eats"
 c = "treats"
 print (a,b,c)
 #Dog eats treats
 d = a + " " + b + " " + c
 print (a)
 #Dog
 print (d)
 #Dog eats treats

আমি একটি ব্লগে আরও সুনির্দিষ্ট ব্যাখ্যা পেয়েছি:

পাইথনে, (প্রায়) সবকিছুই একটি বস্তু। পাইথনে আমরা সাধারণত "ভেরিয়েবল" হিসাবে যা উল্লেখ করি সেগুলিকে আরও সঠিকভাবে নাম বলা হয়। তেমনিভাবে "অ্যাসাইনমেন্ট" হ'ল কোনও বস্তুর সাথে নামের বাঁধাই। প্রতিটি বাঁধার একটি স্পেস থাকে যা তার দৃশ্যমানতা সংজ্ঞায়িত করে, সাধারণত যে ব্লকটিতে নামটির উত্স হয়।

উদাহরণ:

some_guy = 'Fred'
# ...
some_guy = 'George'

যখন আমরা পরে কিছু_গুই = 'জর্জ' বলি, তখন 'ফ্রেড' যুক্ত স্ট্রিং অবজেক্টটি প্রভাবিত হয় না। আমরা সবেমাত্র_বন্ধটির নামটির বাইন্ডিং পরিবর্তন করেছি। তবে আমরা 'ফ্রেড' বা 'জর্জ' স্ট্রিং অবজেক্টগুলিকে পরিবর্তন করি নি। যতদূর আমরা উদ্বিগ্ন, তারা অনির্দিষ্টকালের জন্য বেঁচে থাকতে পারে।

ব্লগের লিঙ্ক: https://jeffknupp.com/blog/2012/11/13/is-python-callbyvalue-or-callbyreferences-neither/


1

উপরে উল্লিখিত উত্তরে কিছুটা যুক্ত করা।

id পুনরায় নিয়োগের উপর একটি পরিবর্তনশীল পরিবর্তন।

>>> a = 'initial_string'
>>> id(a)
139982120425648
>>> a = 'new_string'
>>> id(a)
139982120425776

যার অর্থ হল আমরা aএকটি নতুন স্ট্রিংকে নির্দেশ করতে ভেরিয়েবলটি রূপান্তরিত করেছি । এখন দুটি string (str) অবজেক্ট রয়েছে:

'initial_string'সঙ্গে id= 139982120425648

এবং

'new_string'সঙ্গে id= 139982120425776

নীচের কোডটি বিবেচনা করুন:

>>> b = 'intitial_string'
>>> id(b)
139982120425648

এখন, bপয়েন্টগুলি 'initial_string'এবং পুনরায় নিয়োগের আগে idযেমনটি aছিল তেমন রয়েছে।

সুতরাং, 'intial_string'পরিবর্তন করা হয়নি।


0

সারমর্ম:

a = 3
b = a
a = 3+2
print b
# 5

পরিবর্তনযোগ্য নয়:

a = 'OOP'
b = a
a = 'p'+a
print b
# OOP

অপরিবর্তনীয়:

a = [1,2,3]
b = range(len(a))
for i in range(len(a)):
    b[i] = a[i]+1

পাইথন 3 এ এটি একটি ত্রুটি কারণ এটি পরিবর্তনযোগ্য। পাইথন 2 এ ত্রুটি নয় কারণ এটি স্পষ্টতই তা পরিবর্তনযোগ্য নয়।


0

অন্তর্নির্মিত ফাংশনটি id()একটি পূর্ণসংখ্যা হিসাবে কোনও বস্তুর পরিচয় দেয়। এই পূর্ণসংখ্যা সাধারণত মেমরির মধ্যে অবজেক্টের অবস্থানের সাথে মিলে যায়।

\>>a='dog'
\>>print(id(a))

139831803293008

\>>a=a+'cat'
\>>print(id(a))

139831803293120

প্রাথমিকভাবে, 'এ' 139831803293008 মেমরি অবস্থানের মধ্যে সংরক্ষণ করা হয়, কারণ আপনি যদি স্ট্রিং অবজেক্টটি অজগরতে পরিবর্তন করতে পারেন তবে আপনি যদি সংশোধন ও পুনরায় স্বাক্ষর করার চেষ্টা করেন তবে রেফারেন্সটি সরিয়ে ফেলা হবে এবং একটি নতুন মেমরি অবস্থানের জন্য পয়েন্টার হবে (139831803293120)।


0
a = 'dog'
address = id(a)
print(id(a))

a = a + 'cat'
print(id(a))      #Address changes

import ctypes
ctypes.cast(address, ctypes.py_object).value    #value at old address is intact

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


-1

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

বিভ্রান্তি হ'ল আমরা একই পরিবর্তনশীল নামের সাথে ব্যাকএন্ডে মেমরি ব্লকগুলি (যা ডেটা বা তথ্য ধারণ করে represent) উপস্থাপন করি।


-2

আপনি একটি অদ্ভুত অ্যারে অপরিবর্তনীয় করতে পারেন এবং প্রথম উপাদানটি ব্যবহার করতে পারেন:

numpyarrayname[0] = "write once"

তারপর:

numpyarrayname.setflags(write=False)

অথবা

numpyarrayname.flags.writeable = False
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.