নিম্নলিখিতটি বাদে পাইথনে অন্য একটি স্ট্রিং যুক্ত করার জন্য আমি একটি দক্ষ উপায় চাই।
var1 = "foo"
var2 = "bar"
var3 = var1 + var2
ব্যবহারের জন্য কি কোনও ভাল অন্তর্নির্মিত পদ্ধতি আছে?
নিম্নলিখিতটি বাদে পাইথনে অন্য একটি স্ট্রিং যুক্ত করার জন্য আমি একটি দক্ষ উপায় চাই।
var1 = "foo"
var2 = "bar"
var3 = var1 + var2
ব্যবহারের জন্য কি কোনও ভাল অন্তর্নির্মিত পদ্ধতি আছে?
উত্তর:
যদি আপনার কাছে কেবল একটি স্ট্রিংয়ের একটি রেফারেন্স থাকে এবং আপনি অন্য স্ট্রিংটি শেষের দিকে একত্রিত করেন, সিপিথন এখন এটি বিশেষ মামলা করে এবং স্ট্রিংটি স্থানে প্রসারিত করার চেষ্টা করে।
শেষ ফলাফলটি হ'ল অপারেশনটি এমোরিটাইজড ও (এন) হয়।
যেমন
s = ""
for i in range(n):
s+=str(i)
ও (এন ^ 2) হিসাবে ব্যবহৃত হত, তবে এখন এটি ও (এন)।
উত্স থেকে (bytesobject.c):
void
PyBytes_ConcatAndDel(register PyObject **pv, register PyObject *w)
{
PyBytes_Concat(pv, w);
Py_XDECREF(w);
}
/* The following function breaks the notion that strings are immutable:
it changes the size of a string. We get away with this only if there
is only one module referencing the object. You can also think of it
as creating a new string object and destroying the old one, only
more efficiently. In any case, don't use this if the string may
already be known to some other part of the code...
Note that if there's not enough memory to resize the string, the original
string object at *pv is deallocated, *pv is set to NULL, an "out of
memory" exception is set, and -1 is returned. Else (on success) 0 is
returned, and the value in *pv may or may not be the same as on input.
As always, an extra byte is allocated for a trailing \0 byte (newsize
does *not* include that), and a trailing \0 byte is stored.
*/
int
_PyBytes_Resize(PyObject **pv, Py_ssize_t newsize)
{
register PyObject *v;
register PyBytesObject *sv;
v = *pv;
if (!PyBytes_Check(v) || Py_REFCNT(v) != 1 || newsize < 0) {
*pv = 0;
Py_DECREF(v);
PyErr_BadInternalCall();
return -1;
}
/* XXX UNREF/NEWREF interface should be more symmetrical */
_Py_DEC_REFTOTAL;
_Py_ForgetReference(v);
*pv = (PyObject *)
PyObject_REALLOC((char *)v, PyBytesObject_SIZE + newsize);
if (*pv == NULL) {
PyObject_Del(v);
PyErr_NoMemory();
return -1;
}
_Py_NewReference(*pv);
sv = (PyBytesObject *) *pv;
Py_SIZE(sv) = newsize;
sv->ob_sval[newsize] = '\0';
sv->ob_shash = -1; /* invalidate cached hash value */
return 0;
}
অনুগতভাবে যাচাই করার পক্ষে এটি যথেষ্ট সহজ।
x পাইথন-মি টাইমিটিট-এস "এস = ''" "আমি এক্সরেঞ্জে (10): এস + = 'এ'" 1000000 লুপস, 3 টির মধ্যে সেরা: 1.85 লুপ প্রতি ইউজেক x পাইথন-মি টাইমিটিট-এস "এস = ''" "আমি এক্সরেঞ্জে (100): এস + = 'এ'" 10000 লুপস, 3 লুপের জন্য 16: 16 ইউএসসি সেরা x পাইথন-মি টাইমিটিট-এস "এস = ''" "আই এক্সরেঞ্জে (1000): এস + = 'এ'" 10000 লুপ, প্রতি লুপে 3: 158 ইউএসসি সেরা x পাইথন-মি টাইমিটিট-এস "এস = ''" "আই এক্সরেঞ্জে (10000): এস + = 'এ'" 1000 লুপগুলি, প্রতি লুপে 3: 1.71 মেকসেটের সেরা x পাইথন-মি টাইমিটিট-এস "এস = ''" "আমি এক্সরেঞ্জে (100000): এস + = 'এ'" 10 লুপ, 3 লুপের মধ্যে 14: 14 ম্যাস্কের মধ্যে সেরা x পাইথন-মি টাইমিটিট-এস "এস = ''" "আমি এক্সরেঞ্জে (1000000): এস + = 'এ'" 10 লুপগুলি, প্রতি লুপে 3: 173 এমসির মধ্যে সেরা
এটা গুরুত্বপূর্ণ নোট তবে যে এই অপ্টিমাইজেশান পাইথন বৈশিষ্ট অংশ নয়। এটি কেবলমাত্র পাইপথন বাস্তবায়নে যতদূর আমি জানি। উদাহরণস্বরূপ পাইপী বা জাইথনের উপর একই অভিজ্ঞতামূলক পরীক্ষণটি পুরানো ও (এন ** 2) এর পারফরম্যান্সটি দেখায়।
yp পাইপি-এম টাইমিট -s "এস = ''" "আমি এক্সরেঞ্জে (10): এস + = 'এ'" 10000 লুপ, লুপ প্রতি 3: 90.8 ইউজেকের সেরা x পিঞ্জি-মি টাইমিটিট-এস "এস = ''" "আমি এক্সরেঞ্জে (100): এস + = 'এ'" 1000 লুপ, প্রতি লুপে 3: 896 ইউএসসি সেরা x পিঞ্জি-এম টাইমিট -s "এস = ''" "আমি এক্সরেঞ্জে (1000): এস + = 'এ'" 100 লুপগুলি, প্রতি লুপে 3: 9.03 এমসির মধ্যে সেরা x পিঞ্জি-মি টাইমিটিট-এস "এস = ''" "আমি এক্সরেঞ্জে (10000): এস + = 'এ'" 10 লুপগুলি, প্রতি লুপে 3: 89.5 ম্যাস্কের মধ্যে সেরা
এখন পর্যন্ত এত ভাল, কিন্তু তারপর,
x পিঞ্জি-মি টাইমিটিট-এস "এস = ''" "আমি এক্সরেঞ্জে (100000): এস + = 'এ'" 10 লুপ, প্রতি লুপে 3: 12.8 সেকেন্ডের মধ্যে সেরা
চতুর্ভুজ এর চেয়েও খারাপ worse সুতরাং পাইপি এমন কিছু করছে যা সংক্ষিপ্ত স্ট্রিংয়ের সাথে ভালভাবে কাজ করে তবে বড় স্ট্রিংয়ের জন্য খারাপ কাজ করে।
PyString_ConcatAndDel
ফাংশনটি উদ্ধৃত করেছেন তবে এর জন্য মন্তব্যটি অন্তর্ভুক্ত করেছেন _PyString_Resize
। এছাড়াও, মন্তব্যটি বিগ-ও সম্পর্কিত আপনার দাবীটি সত্যই প্রতিষ্ঠিত করে না
"".join(str_a, str_b)
অকালে অপটিমাইজ করবেন না। আপনার যদি বিশ্বাস করার কোনও কারণ না থাকে যে স্ট্রিং কনটেন্টেশনের কারণে গতির বাধা রয়েছে তবে কেবল +
এবং এর সাথে আটকে থাকুন +=
:
s = 'foo'
s += 'bar'
s += 'baz'
এটি বলেছিল, আপনি যদি জাভার স্ট্রিংবিল্ডারের মতো কোনও কিছুর সন্ধান করছেন, তবে ক্যানোনিকাল পাইথন আইডিয়মটি তালিকায় আইটেম যুক্ত করতে হবে এবং তারপরে সবগুলি সংক্ষেপে ব্যবহার str.join
করতে হবে:
l = []
l.append('foo')
l.append('bar')
l.append('baz')
s = ''.join(l)
str1 = "Hello"
str2 = "World"
newstr = " ".join((str1, str2))
এটি বিভাজক হিসাবে একটি স্থানের সাথে str1 এবং str2 এ যোগ দেয়। আপনি করতে পারেন "".join(str1, str2, ...)
। str.join()
একটি পুনরাবৃত্তযোগ্য লাগে, সুতরাং আপনি একটি তালিকা বা একটি tuple মধ্যে স্ট্রিং রাখতে হবে।
এটি বিল্টিন পদ্ধতির জন্য যতটা দক্ষ তা প্রায় কার্যকর।
না।
এটি হ'ল বেশিরভাগ ক্ষেত্রে আপনি বিদ্যমান স্ট্রিংয়ের সাথে যুক্ত হয়ে এক সাথে পুরো স্ট্রিং তৈরি করা ভাল better
উদাহরণস্বরূপ, করবেন না: obj1.name + ":" + str(obj1.count)
পরিবর্তে: ব্যবহার "%s:%d" % (obj1.name, obj1.count)
এটি পড়া সহজ এবং আরও দক্ষ হবে।
"<div class='" + className + "' id='" + generateUniqueId() + "'>" + message_text + "</div>"
, আমি তখন কম পঠনযোগ্য এবং ত্রুটি-প্রবণ খুঁজে পাই"<div class='{classname}' id='{id}'>{message_text}</div>".format(classname=class_name, message_text=message_text, id=generateUniqueId())
পাইথন ৩.6 আমাদের এফ স্ট্রিং দেয় যা একটি আনন্দের বিষয়:
var1 = "foo"
var2 = "bar"
var3 = f"{var1}{var2}"
print(var3) # prints foobar
আপনি কোঁকড়া ধনুর্বন্ধনী এর ভিতরে সর্বাধিক কিছু করতে পারেন
print(f"1 + 1 == {1 + 1}") # prints 1 + 1 == 2
বড় স্ট্রিং তৈরি করতে আপনার যদি অনেক অ্যাপেনড অপারেশন করতে হয় তবে আপনি স্ট্রিংআইও বা সিস্ট্রিংআইও ব্যবহার করতে পারেন । ইন্টারফেসটি একটি ফাইলের মতো। যেমন: আপনি write
এটিতে পাঠ্য যোগ করতে পারেন।
আপনি যদি কেবল দুটি স্ট্রিং যুক্ত করে থাকেন তবে কেবল ব্যবহার করুন +
।
মূলত, কোনও পার্থক্য নেই। একমাত্র ধারাবাহিক প্রবণতা হ'ল পাইথন প্রতিটি সংস্করণের সাথে ধীর হয়ে যাচ্ছে ... :(
%%timeit
x = []
for i in range(100000000): # xrange on Python 2.7
x.append('a')
x = ''.join(x)
পাইথন 2.7
1 লুপ, প্রতি লুপ 3: 7.34 এর মধ্যে সেরা
পাইথন ৩.৪
1 লুপ, প্রতি লুপ 3: 7.99 এর মধ্যে সেরা
পাইথন ৩. 3.5
1 লুপ, প্রতি লুপে 3: 8.48 এর মধ্যে সেরা
পাইথন ৩.6
1 লুপ, প্রতি লুপ 3: 9.93 এস এর মধ্যে সেরা
%%timeit
x = ''
for i in range(100000000): # xrange on Python 2.7
x += 'a'
পাইথন ২.7 :
1 লুপ, প্রতি লুপ 3: 7.41 এর মধ্যে সেরা
পাইথন ৩.৪
1 লুপ, প্রতি লুপ 3: 9.08 এর মধ্যে সেরা
পাইথন ৩. 3.5
1 লুপ, প্রতি লুপে 3: 8.82 এর মধ্যে সেরা
পাইথন ৩.6
1 লুপ, প্রতি লুপ 3: 9.24 এস এর মধ্যে সেরা
1.19 s
এবং 992 ms
Python2.7 উপর যথাক্রমে
__add__ ফাংশন সহ স্ট্রিংগুলি যুক্ত করুন
str = "Hello"
str2 = " World"
st = str.__add__(str2)
print(st)
আউটপুট
Hello World
str + str2
এখনও খাটো।
a='foo'
b='baaz'
a.__add__(b)
out: 'foobaaz'
a.__add__(b)
লেখার জন্য অভিন্ন a+b
। আপনি যখন +
অপারেটরটি ব্যবহার করে স্ট্রিংগুলি সংহত করেন , পাইথন __add__
প্যারামিটার হিসাবে ডান পাশের স্ট্রিংটি বাম দিকে স্ট্রিংয়ের পদ্ধতিটি কল করবে ।
"foo" + "bar" + str(3)