از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
پایتون: شمارش تعداد رخدادهای زیر رشته ای در رشته
سرفصلهای مطلب
معرفی
آ رشته فرعی دنباله ای پیوسته از کاراکترها در a است رشته. برای مثال، "substring"
زیر رشته ای از "Find a substring within a string"
.
رشته ها در پایتون آرایه هایی از بایت ها هستند که نشان می دهند یونیکد کاراکترها و یکی از متداولترین انواع دادهها برای نمایش دادهها در قالبی قابل خواندن برای انسان است.
در این مقاله می آموزیم که چگونه تعداد وقوع یک زیررشته مشخص شده در یک رشته را بشماریم. پایتون.
با استفاده از تمام موارد وقوع یک رشته فرعی در یک رشته را پیدا کنید شمردن()
را count()
متد کلاس رشته در واقع انجام می دهد فقط همین. تعداد دفعاتی که یک مقدار مشخص (زیر رشته) در رشته ظاهر می شود را برمی گرداند. همچنین دارای دو پارامتر اختیاری است – start
و end
، شروع و پایان فضای جستجو را نشان می دهد:
string.count(value, start, end)
توجه داشته باشید: به طور پیش فرض start
است 0
و پیش فرض است end
طول رشته است.
بیایید نگاهی به استفاده از روش بیندازیم، با یک جمله نماینده:
str1 = 'John has 1 apple, Sarah has 2 apples, Mike has 5 apples.'
substr = 'apples'
result = str1.count(substr)
print("Number of substring occurrences:", result)
start, end = 0, 40
result2 = str1.count(substr, start, end)
print("Number of substring occurrences:", result2)
این نتیجه در:
Number of substring occurrences: 2
Number of substring occurrences: 1
این یک روش بسیار ساده و سرراست است که در بیشتر موارد به خوبی جواب می دهد. کارآمد است و میتواند به اندازههای ورودی بزرگ افزایش یابد. به عنوان مثال، ما میتوانیم در یک متن بزرگ بارگذاری کنیم و یک کلمه معمولی یا یک کلمه توقف را جستجو کنیم. مقید شده است حاضر شدن.
شما همچنین می توانید به سادگی یک فضای جستجوی بزرگ را به دست آورید تا کارایی را درک کنید. بیایید «رومئو و ژولیت» اثر ویلیام شکسپیر را از پروژه گوتنبرگ دانلود کنیم و تعداد دفعات را بازیابی کنیم. 'Romeo'
اشاره شده است:
import time
import requests
txt = requests.get('https://www.gutenberg.org/cache/epub/1513/pg1513.txt').text
print(f"Downloaded {len(txt)} bytes of text...")
start_time = time.time()
count = txt.count('Romeo')
end_time = time.time()
print(f"Time to find all occurrences of 'Romeo': {end_time - start_time}s with {count} results")
این نتیجه در:
Downloaded 167333 bytes of text...
Time to find all occurrences of 'Romeo': 0.0s with 153 results
یا، حتی اگر ما پیدا کنیم بسیار کلمه رایج تر، مانند 'a'
:
start_time = time.time()
count = txt.count('a')
end_time = time.time()
print(f"Time to find all occurrences of 'a': {end_time - start_time}s with {count} results")
نتیجه یکسان است:
Downloaded 167333 bytes of text...
Time to find all occurrences of 'Romeo': 0.0s with 8308 results
بخش اعظم زمان اجرا به زمان دانلود متن اختصاص می یابد.
توجه داشته باشید: این روش موقعیتی را در رشته ای که رشته فرعی در آن رخ می دهد بر نمی گرداند.
اگر به این دانش نیاز دارید، یا برای انجام عملیات تبدیلی اضافی روی رخدادها علاوه بر شمارش آنها – می خواهید از a استفاده کنید عبارات با قاعده برای یافتن موقعیت های خود یا بررسی موارد فردی با startsWith()
.
در بخش های بعدی به بررسی این دو مورد خواهیم پرداخت.
تمام رخدادها و موقعیت های یک زیر رشته را در یک رشته در پایتون پیدا کنید
را startswith()
روش برمی گرداند True
اگر رشته با مشخص شده شروع شود value
(زیر رشته) و False
اگر آن را ندارد. مشابه به count()
روش، این روش همچنین دارای پارامترهای اختیاری است شروع کنید و پایان که موقعیت های شروع و پایان فضای جستجو را مشخص می کند:
string.startswith(value, start, end)
به طور پیش فرض start
ارزش است 0
و پیش فرض end
مقدار طول رشته است.
استفاده از این روش کمی پیچیده تر است، زیرا ما را ملزم به استفاده از درک لیست همراه با خود روش یا روش سنتی تر می کند. for
حلقه را startswith()
روش شاخص های اولیه بستر را برمی گرداند. پس از آن ما از درک لیست برای تکرار در کل فضای جستجو استفاده می کنیم:
str1 = 'John has 1 apple, Sarah has 2 apples, Mike has 5 apples.'
substr = 'apples'
print("Original string is:", str1)
print("Substring is:", substr)
result = (i for i in range(len(str1)) if str1.startswith(substr, i))
print("Number of substring occurrences is:", len(result))
print("Starting indices of substrings are: " + str(result))
این تعداد وقایع را مانند آخرین بار به ما می دهد ، اما همچنین موقعیت های شروع خود رشته ها. از آنجا که ما رشته مورد نظر را می شناسیم و به این ترتیب ، طول آن – می توانیم به راحتی فضایی را که در رشته جستجو اشغال می کند ، استنباط کنیم:
Original string is: John has 1 apple, Sarah has 2 apples, Mike has 5 apples.
Substring is: apples
Number of substring occurrences is: 2
Starting indices of substrings are: (30, 49)
تمام وقایع یک بستر را در یک رشته در پایتون با استفاده از آن پیدا کنید re.finditer()
را finditer()
تابع بخشی از کتابخانه RegEx پایتون است – re
. معمولاً برای یافتن وقوع یک الگوی خاص در یک رشته معین استفاده می شود.
برای فعال کردن استفاده از این روش، همراه با بسیاری از روشهای دیگر که عبارات RegEx را مدیریت میکنند، ابتدا باید import کتابخانه regex:
re.finditer(pattern, string, flags=0)
اگر می خواهید در مورد عبارات منظم اطلاعات بیشتری کسب کنید ، راهنمای ما برای عبارات منظم در پایتون را بخوانید!
را re.finditer()
عملکرد یک تکرار کننده اشیاء همسان با تمام مسابقات غیر همپوشانی برای Regex را برمی گرداند الگو در یک رشته. اسکن از چپ به راست انجام می شود و مسابقات به ترتیب پیدا شده در آن بازگردانده می شوند. مسابقات خالی نیز گنجانده شده است.
از پرچم ها می توان برای فعال کردن ویژگی های منحصر به فرد مختلف و تغییرات نحوی استفاده کرد (به عنوان مثال، re.I
یا re.IGNORECASE
پرچم تطبیق غیر حساس به حروف بزرگ را فعال می کند، re.A
یا re.ASCII
پرچم را فعال می کند ASCII
فقط مطابق به جای کامل معمولی UNICODE
تطابق).
بیایید درک لیست را از قبل با یک عبارت معمولی جایگزین کنیم:
import re
str1 = 'John has 1 apple, Sarah has 2 apples, Mike has 5 apples.'
substr = 'apples'
print("Original string is:", str1)
print("Substring is:", substr)
result = ((_.start(), _.end()) for _ in re.finditer(substr, str1))
print("Number of substring occurrences is:", len(result))
print("The start and end indices of the substrings are: " + str(result))
این نتیجه در:
Original string is: John has 1 apple, Sarah has 2 apples, Mike has 5 apples.
Substring is: apples
Number of substring occurrences is: 2
The start and end indices of the substrings are: ((30, 36), (49, 55))
در حال حاضر، ما مجبور نیستیم به صورت دستی طول رشته ها را به شاخص های شروع اضافه کنیم.
ارزیابی عملکرد
شایان ذکر است که عملکرد بر اساس متفاوت خواهد بود روی روشی که انتخاب می کنید در حالی که در همه موارد، کد به سرعت به پایان می رسد – هنوز هم ارزش آن را دارد که عملکرد را در نظر بگیرید روی واقعا فضاهای جستجوی بزرگ
بیایید از این سه روش برای یافتن تمام نمونه های کاراکتر استفاده کنیم 'a'
که در ‘رومئو و ژولیت’:
import re
import time
import requests
txt = requests.get('https://www.gutenberg.org/cache/epub/1513/pg1513.txt').text
print(f"Downloaded {len(txt)} bytes of text...")
start_time_1 = time.time()
result_1 = txt.count('a')
end_time_1 = time.time()
print(f"String.count(): Time to find all occurrences of 'a': {end_time_1 - start_time_1}s")
start_time_2 = time.time()
result_2 = (i for i in range(len(txt)) if txt.startswith('a', i))
end_time_2 = time.time()
print(f"List Comprehensions: Time to find all occurrences of 'a': {end_time_2 - start_time_2}s")
start_time_3 = time.time()
result_3 = ((_.start(), _.end()) for _ in re.finditer('a', txt))
end_time_3 = time.time()
print(f"Regex: Time to find all occurrences of 'a': {end_time_3 - start_time_3}s")
این نتیجه در:
String.count(): Time to find all occurrences of 'a': 0.0s
List Comprehensions: Time to find all occurrences of 'a': 0.031008481979370117s
Regex: Time to find all occurrences of 'a': 0.002000093460083008s
را count()
روش قطعا کارآمدترین روش است، اما به ما اطلاع نمی دهد جایی که رشته ها هستند. برای دانش اضافی – عبارات منظم هنوز برای این کار بسیار سریع هستند و بیش از 10 برابر کارآمدتر از حلقه درک لیست دستی ما هستند.
نتیجه
چندین راه مختلف برای حل این مشکل وجود دارد، بسته به اینکه برخی از آنها بیشتر از دیگران استفاده می شوند روی داده هایی که می خواهید در آن استخراج کنید process.
در معیار، count()
روش بهتر از دو روش دیگر بود، اما اطلاعاتی به ما نمی دهد روی جایی که رشته های فرعی در آن قرار دارند. از طرف دیگر، Regular Expressions، هر چند کندتر، این اطلاعات را در اختیار ما قرار می دهد.
شایان ذکر است که هر سه رویکرد فوق العاده سریع هستند و می توانند کل یک شاهکار ادبی را برای یک کلمه رایج در کسری از ثانیه تجزیه کنند.
(برچسبها به ترجمه)# python
منتشر شده در 1403-01-07 21:26:03