একটি স্ট্রিংয়ের মধ্যে সাবস্ট্রিংয়ের নবম উপস্থিতি সন্ধান করুন


118

এটি দেখতে বেশ তুচ্ছ হওয়া উচিত বলে মনে হচ্ছে তবে আমি পাইথনে নতুন এবং এটিকে সবচেয়ে পাইথোনিক উপায়ে করতে চাই।

আমি একটি স্ট্রিংয়ের মধ্যে একটি স্ট্রিংয়ের n'তম ঘটনার সাথে সম্পর্কিত সূচকটি খুঁজতে চাই।

আমি যা করতে চাই তার সমতুল্য কিছু হতে পারে

mystring.find("substring", 2nd)

পাইথনে আপনি কীভাবে এটি অর্জন করতে পারেন?


7
স্ট্রিং এর n'th উপস্থিতি খুঁজে? আমি ধরে নিচ্ছি এর অর্থ হল 'এন' ঘটনাটির সূচক?
মার্ক বাইয়ার্স

2
হ্যাঁ, নবম ঘটনার সূচক
প্রেস্টোমেশন

9
ওভারল্যাপিং মিল থাকলে কী হবে? সন্ধান করা উচিত ('আআআআআ', 'আ', ২) 1 বা 2 ফিরবে?
মার্ক বাইয়ার্স

হ্যাঁ! স্ট্রিংয়ের একটি স্ট্রিংয়ের n'th উপস্থিতি খুঁজে পাওয়ার জন্য এবং স্ট্রিংয়ের n'th সংঘটনগুলিতে স্ট্রিংকে বিভক্ত করার জন্য এখানে কিছু রয়েছে।
রেমান

উত্তর:


69

মার্ক এর পুনরাবৃত্তি পদ্ধতির স্বাভাবিক উপায় হবে, আমি মনে করি।

এখানে স্ট্রিং-বিভক্তকরণের একটি বিকল্প রয়েছে যা প্রায়শই সম্পর্কিত-সম্পর্কিত প্রক্রিয়াগুলির জন্য কার্যকর হতে পারে:

def findnth(haystack, needle, n):
    parts= haystack.split(needle, n+1)
    if len(parts)<=n+1:
        return -1
    return len(haystack)-len(parts[-1])-len(needle)

এবং এখানে একটি দ্রুত (এবং কিছুটা নোংরা, এখানে আপনাকে কিছু খড় বেছে নিতে হবে যা সূচির সাথে মেলে না) ওয়ান-লাইনার:

'foo bar bar bar'.replace('bar', 'XXX', 1).find('bar')

7
আপনার আগ্রহের ম্যাচটি শুরু হওয়ার সময় প্রথম পরামর্শটি বড় স্ট্রিংগুলির জন্য খুব অদক্ষ হতে চলেছে। এটি সর্বদা পুরো স্ট্রিং এ দেখায়। এটি বুদ্ধিমান তবে আমি পাইথনের কাছে নতুন এবং এটি করার জন্য একটি ভাল উপায় শিখতে চাইছি এমন কাউকে এটির পরামর্শ দেব না।
মার্ক বাইয়ার্স

3
ধন্যবাদ, আমি আপনার এক লাইনার পছন্দ করি আমি মনে করি না এটি বিশ্বের সবচেয়ে তাত্ক্ষণিকভাবে পঠনযোগ্য জিনিস, তবে এটি নীচের বেশিরভাগ লোকের চেয়ে খুব খারাপ কিছু নয়
প্রিস্টোমেশন

1
ওয়ান-লাইনারের জন্য +1, এটি এখনই আমাকে সহায়তা করবে। আমি এর সমতুল্য করার কথা ভাবছিলাম .rfind('XXX'), তবে 'XXX'যাইহোক ইনপুটটিতে পরে প্রদর্শিত হলে তা বিচ্ছিন্ন হয়ে যাবে ।
নিখিল চেলিয়াহ

এই ফাংশনটি এন = 0, 1, 2, 3, ... ধরে নেওয়া ভাল লাগবে আপনি এন = 1, 2, 3, 4, ... ধরে নেবেন ...
শুভ

75

সোজা পুনরাবৃত্ত সমাধানের আরও পাইথোনিক সংস্করণ এখানে:

def find_nth(haystack, needle, n):
    start = haystack.find(needle)
    while start >= 0 and n > 1:
        start = haystack.find(needle, start+len(needle))
        n -= 1
    return start

উদাহরণ:

>>> find_nth("foofoofoofoo", "foofoo", 2)
6

আপনি যদি নবম ওভারল্যাপিংয়ের ঘটনাটি সন্ধান করতে চান তবে আপনি এর পরিবর্তে needleবৃদ্ধি করতে পারেন :1len(needle)

def find_nth_overlapping(haystack, needle, n):
    start = haystack.find(needle)
    while start >= 0 and n > 1:
        start = haystack.find(needle, start+1)
        n -= 1
    return start

উদাহরণ:

>>> find_nth_overlapping("foofoofoofoo", "foofoo", 2)
3

মার্কের সংস্করণটির চেয়ে এটি পড়া সহজ, এবং এর জন্য বিভাজন সংস্করণ বা নিয়মিত এক্সপ্রেশন মডিউল আমদানি করার অতিরিক্ত মেমরির প্রয়োজন হয় না। এটি পাইথনের জেনের বিভিন্ন reপদ্ধতির বিপরীতে কয়েকটি নিয়মকে মেনে চলে :

  1. সহজ জটিল চেয়ে ভাল।
  2. নেস্টেড থেকে ফ্ল্যাট ভাল।
  3. পঠনযোগ্যতা গণনা।

এটি কি স্ট্রিংয়ে করা যায়? 'X' এর ২ য় দৃষ্টান্তের অবস্থান অনুসন্ধান করতে Find_nth (df.mystring.str, ('x'), 2) এর মতো?
আর্থার ডি হাওল্যান্ড 23:58

36

এটি স্ট্রিংয়ের মধ্যে সাবস্ট্রিংয়ের দ্বিতীয় ঘটনাটি খুঁজে পাবে।

def find_2nd(string, substring):
   return string.find(substring, string.find(substring) + 1)

সম্পাদনা: আমি পারফরম্যান্স সম্পর্কে খুব বেশি ভাবিনি, তবে দ্রুত পুনরাবৃত্তি নবম ঘটনাটি সন্ধান করতে সহায়তা করতে পারে:

def find_nth(string, substring, n):
   if (n == 1):
       return string.find(substring)
   else:
       return string.find(substring, find_nth(string, substring, n - 1) + 1)

এন-তম উপাদানটি খুঁজতে এটি কি সাধারণত বাড়ানো যেতে পারে?
ifly6

এটি সেরা উত্তর আইএমএইচও, আমি বিশেষ মামলার জন্য একটি ছোট সংযোজন করেছি যেখানে এন = 0
জান উইলম্যানস

আমি ব্রিভিটির জন্য পোস্টটি সম্পাদনা করতে চাইনি। যদিও আমি আপনার সাথে একমত, সেই এন = 0 কে একটি বিশেষ কেস হিসাবে বিবেচনা করা উচিত।
শ্রীরাম মুরালি

nসাবস্ট্রিংয়ের ঘটনাগুলির চেয়ে কম যেখানে আছে তার ক্ষেত্রে এটি পরিচালনা করতে সামঞ্জস্য করা উচিত । (এক্ষেত্রে রিটার্নের মান পর্যায়ক্রমে সমস্ত উপস্থিতি পজিশনের মধ্যে দিয়ে যাবে)
শীতফিক্স

29

রেজেক্স সর্বদা সেরা সমাধান নয় তা বুঝতে পেরে আমি সম্ভবত এখানে একটি ব্যবহার করব:

>>> import re
>>> s = "ababdfegtduab"
>>> [m.start() for m in re.finditer(r"ab",s)]
[0, 2, 11]
>>> [m.start() for m in re.finditer(r"ab",s)][2] #index 2 is third occurrence 
11

4
অবশ্যই এখানে ঝুঁকিটি হ'ল অনুসন্ধানের স্ট্রিংটিতে বিশেষ অক্ষর থাকবে যা রেজেক্সকে এমন কিছু করতে দেবে যা আপনি চান না। Re.escape ব্যবহার করে এটি সমাধান করা উচিত।
মার্ক বাইয়ার্স

1
এটি চতুর, তবে এটি কি সত্যই পাইথোনিক? কেবলমাত্র একটি স্ট্রস্ট্রিংয়ের নবম ঘটনাটি খুঁজে পাওয়ার জন্য ওভারকিলের মতো মনে হয় এবং এটি পড়া ঠিক ঠিক সহজ নয়। এছাড়াও, যেমন আপনি বলেছেন, আপনাকে এর জন্য পুনরায় সমস্ত কিছু আমদানি করতে হবে
টড গাম্বলিন

আপনি যখন বর্গক্ষেত্র বন্ধনী ব্যবহার করেন, আপনি পাইথনকে পুরো তালিকা তৈরি করতে বলেন। গোলাকার বন্ধনীগুলি কেবল প্রথম উপাদানগুলির মাধ্যমে পুনরাবৃত্তি হবে, যা আরও কার্যকর:(m.start() for m in re.finditer(r"ab",s))[2]
ইমু

1
@ এমু না, আপনি যা পোস্ট করেছেন তা কাজ করবে না; আপনি কোনও জেনারেটরের সূচক নিতে পারবেন না।
মার্ক আমেরিকা

@ মার্কআমেরি দুঃখিত! আমি কেন এই কোডটি পোস্ট করেছি তা নিয়ে আমি বেশ অবাক হয়েছি। তবুও, একটি অনুরূপ এবং কদর্য সমাধানটি itertools.isliceফাংশনটি ব্যবহার করে সম্ভব :next(islice(re.finditer(r"ab",s), 2, 2+1)).start()
ইমু

17

আমি সবচেয়ে বিশিষ্ট পন্থা তুলনা কিছু মাপকাঠিতে ফলাফল এতদূর উপস্থাপন প্রস্তাব করছি, যথা bobince এর @ findnth()(উপর ভিত্তি করে str.split()) বনাম @ tgamblin বা @Mark Byers ' find_nth()(উপর ভিত্তি করে str.find())। _find_nth.soআমরা কত দ্রুত যেতে পারি তা দেখতে আমি একটি সি এক্সটেনশনের ( ) এর সাথেও তুলনা করব । এখানে find_nth.py:

def findnth(haystack, needle, n):
    parts= haystack.split(needle, n+1)
    if len(parts)<=n+1:
        return -1
    return len(haystack)-len(parts[-1])-len(needle)

def find_nth(s, x, n=0, overlap=False):
    l = 1 if overlap else len(x)
    i = -l
    for c in xrange(n + 1):
        i = s.find(x, i + l)
        if i < 0:
            break
    return i

অবশ্যই, স্ট্রিং বড় হলে পারফরম্যান্স সর্বাধিক গুরুত্বপূর্ণ, সুতরাং ধরুন আমরা 'বিগফিল' নামক একটি 1.3 গিগাবাইট ফাইলে 1000001 তম নিউলাইন ('\ n') সন্ধান করতে চাই। স্মৃতি সংরক্ষণ করতে, আমরা mmap.mmapফাইলটির একটি উপস্থাপনের কাজ করতে চাই :

In [1]: import _find_nth, find_nth, mmap

In [2]: f = open('bigfile', 'r')

In [3]: mm = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)

ইতিমধ্যে প্রথম সমস্যা রয়েছে findnth(), যেহেতু mmap.mmapবস্তুগুলি সমর্থন করে না split()। সুতরাং আমাদের আসলে পুরো ফাইলটি মেমরিতে অনুলিপি করতে হবে:

In [4]: %time s = mm[:]
CPU times: user 813 ms, sys: 3.25 s, total: 4.06 s
Wall time: 17.7 s

সেকি! ভাগ্যক্রমে sএখনও আমার ম্যাকবুক এয়ারের 4 গিগাবাইট মেমরি ফিট করে, তাই আসুন বেনমার্ক করুন findnth():

In [5]: %timeit find_nth.findnth(s, '\n', 1000000)
1 loops, best of 3: 29.9 s per loop

স্পষ্টত একটি ভয়াবহ অভিনয়। আসুন দেখে নেওয়া যাক কীভাবে ভিত্তিক পদ্ধতিটি str.find()করে:

In [6]: %timeit find_nth.find_nth(s, '\n', 1000000)
1 loops, best of 3: 774 ms per loop

অনেক ভাল! স্পষ্টতই, findnth()সমস্যাটি হ'ল এটি সময়কালে স্ট্রিংটি অনুলিপি করতে বাধ্য হয় split()যা ইতিমধ্যে দ্বিতীয়বারের মতো আমরা প্রায় 1.3 জিবি ডেটা অনুলিপি করেছি s = mm[:]। এখানে দ্বিতীয় সুবিধাটি আসে find_nth(): আমরা এটি mmসরাসরি ব্যবহার করতে পারি , যেমন ফাইলের শূন্য অনুলিপিগুলি প্রয়োজন:

In [7]: %timeit find_nth.find_nth(mm, '\n', 1000000)
1 loops, best of 3: 1.21 s per loop

সেখানে একটি ছোট কর্মক্ষমতা শাস্তি অপারেটিং উপস্থিত হতে পারে mmবনাম s, কিন্তু এই দেখায় যে, find_nth()আমাদের 1.2 s এ একটি উত্তর তুলনায় পেতে পারেনfindnth 47 s এর 'র মোট।

str.find()ভিত্তিক পদ্ধতির চেয়ে str.split()ভিত্তিক পদ্ধতির তুলনায় খারাপ অবস্থার এমন কোনও ঘটনা আমি খুঁজে পাইনি , সুতরাং এই মুহুর্তে আমি যুক্তি দেব যে @ টগাম্বলিন বা @ মার্ক বাইয়ার্সের উত্তর @ ববিন্সের পরিবর্তে গ্রহণ করা উচিত।

আমার পরীক্ষায়, find_nth()উপরের সংস্করণটি ছিল আমি দ্রুততম খাঁটি পাইথন সমাধানটি নিয়ে আসতে পারি (@ মার্ক বাইয়ার্স সংস্করণটির সাথে খুব মিল)। আসুন দেখি আমরা একটি সি এক্সটেনশন মডিউল দিয়ে আরও কত ভাল করতে পারি। এখানে _find_nthmodule.c:

#include <Python.h>
#include <string.h>

off_t _find_nth(const char *buf, size_t l, char c, int n) {
    off_t i;
    for (i = 0; i < l; ++i) {
        if (buf[i] == c && n-- == 0) {
            return i;
        }
    }
    return -1;
}

off_t _find_nth2(const char *buf, size_t l, char c, int n) {
    const char *b = buf - 1;
    do {
        b = memchr(b + 1, c, l);
        if (!b) return -1;
    } while (n--);
    return b - buf;
}

/* mmap_object is private in mmapmodule.c - replicate beginning here */
typedef struct {
    PyObject_HEAD
    char *data;
    size_t size;
} mmap_object;

typedef struct {
    const char *s;
    size_t l;
    char c;
    int n;
} params;

int parse_args(PyObject *args, params *P) {
    PyObject *obj;
    const char *x;

    if (!PyArg_ParseTuple(args, "Osi", &obj, &x, &P->n)) {
        return 1;
    }
    PyTypeObject *type = Py_TYPE(obj);

    if (type == &PyString_Type) {
        P->s = PyString_AS_STRING(obj);
        P->l = PyString_GET_SIZE(obj);
    } else if (!strcmp(type->tp_name, "mmap.mmap")) {
        mmap_object *m_obj = (mmap_object*) obj;
        P->s = m_obj->data;
        P->l = m_obj->size;
    } else {
        PyErr_SetString(PyExc_TypeError, "Cannot obtain char * from argument 0");
        return 1;
    }
    P->c = x[0];
    return 0;
}

static PyObject* py_find_nth(PyObject *self, PyObject *args) {
    params P;
    if (!parse_args(args, &P)) {
        return Py_BuildValue("i", _find_nth(P.s, P.l, P.c, P.n));
    } else {
        return NULL;    
    }
}

static PyObject* py_find_nth2(PyObject *self, PyObject *args) {
    params P;
    if (!parse_args(args, &P)) {
        return Py_BuildValue("i", _find_nth2(P.s, P.l, P.c, P.n));
    } else {
        return NULL;    
    }
}

static PyMethodDef methods[] = {
    {"find_nth", py_find_nth, METH_VARARGS, ""},
    {"find_nth2", py_find_nth2, METH_VARARGS, ""},
    {0}
};

PyMODINIT_FUNC init_find_nth(void) {
    Py_InitModule("_find_nth", methods);
}

setup.pyফাইলটি এখানে :

from distutils.core import setup, Extension
module = Extension('_find_nth', sources=['_find_nthmodule.c'])
setup(ext_modules=[module])

যথারীতি ইনস্টল করুন python setup.py install। সি কোডটি এখানে একটি সুবিধে খেলছে কারণ এটি একক অক্ষরগুলি সন্ধানের মধ্যে সীমাবদ্ধ, তবে আসুন দেখি এটি কত দ্রুত:

In [8]: %timeit _find_nth.find_nth(mm, '\n', 1000000)
1 loops, best of 3: 218 ms per loop

In [9]: %timeit _find_nth.find_nth(s, '\n', 1000000)
1 loops, best of 3: 216 ms per loop

In [10]: %timeit _find_nth.find_nth2(mm, '\n', 1000000)
1 loops, best of 3: 307 ms per loop

In [11]: %timeit _find_nth.find_nth2(s, '\n', 1000000)
1 loops, best of 3: 304 ms per loop

স্পষ্টত বেশ খানিকটা দ্রুত এখনও। মজার বিষয় হল, মেমোরি এবং এমএম্যাপ করা মামলার মধ্যে সি স্তরের কোনও পার্থক্য নেই। এটি দেখতেও আকর্ষণীয় যে _find_nth2()এটি string.h' memchr()লাইব্রেরি ফাংশনের উপর ভিত্তি করে তৈরি হয়েছে যা সরাসরি প্রয়োগের বিরুদ্ধে হারাতে পারে _find_nth(): অতিরিক্ত "অপ্টিমাইজেশন" ইনmemchr() স্পষ্টতই ব্যাকফায়ারিং ...

উপসংহারে, findnth()(এর উপর ভিত্তি করে str.split()) বাস্তবায়নটি একটি খারাপ ধারণা, যেহেতু (ক) এটি প্রয়োজনীয় অনুলিপিটির কারণে বৃহত্তর স্ট্রিংয়ের জন্য ভয়ানকভাবে সম্পাদন করে, এবং (খ) এটি mmap.mmapবস্তুগুলিতে মোটেই কাজ করে না । বাস্তবায়ন find_nth()(উপর ভিত্তি করে)str.find() ) ক্ষেত্রে সকল পরিস্থিতিতে অগ্রাধিকার দেওয়া উচিত (এবং তাই এই প্রশ্নের গ্রহণযোগ্য উত্তর হতে হবে)।

উন্নয়নের জন্য এখনও বেশ কিছুটা জায়গা রয়েছে, যেহেতু সি এক্সটেনশন খাঁটি পাইথন কোডের চেয়ে প্রায় 4 টির একটি ফ্যাক্টর দৌড়েছিল, এটি ইঙ্গিত করে যে ডেডিকেটেড পাইথন লাইব্রেরি ফাংশনের ক্ষেত্রে কেস থাকতে পারে।


8

সহজ উপায়?

text = "This is a test from a test ok" 

firstTest = text.find('test')

print text.find('test', firstTest + 1)

আমি ভাবতে পারি যে অন্যান্য সমাধানের তুলনায় এটিও বেশ পারফরম্যান্স।
রোটেরেটি

7

আমি সম্ভবত এটির মতো কিছু করব, সন্ধানের ফাংশনটি ব্যবহার করে যা সূচকের পরামিতি নেয়:

def find_nth(s, x, n):
    i = -1
    for _ in range(n):
        i = s.find(x, i + len(x))
        if i == -1:
            break
    return i

print find_nth('bananabanana', 'an', 3)

এটি অনুমান করা বিশেষত পাইথোনিক নয়, তবে এটি সহজ। পরিবর্তে পুনরাবৃত্তি ব্যবহার করে আপনি এটি করতে পারেন:

def find_nth(s, x, n, i = 0):
    i = s.find(x, i)
    if n == 1 or i == -1:
        return i 
    else:
        return find_nth(s, x, n - 1, i + len(x))

print find_nth('bananabanana', 'an', 3)

এটি সমাধানের এটি কার্যকরী উপায়, তবে আমি জানি না যে এটি এটিকে আরও পাইথোনিক করে তোলে কিনা।


1
for _ in xrange(n):while n: ... n-=1
21f18 এ

@ জেএফ সেবাস্তিয়ান: হ্যাঁ, আমি অনুমান করি যে এটি একটু বেশি পাইথোনিক। আমি আপডেট করব।
মার্ক বাইয়ার্স

বিটিডাব্লু: এক্সরেঞ্জের আর পাইথন 3: ডাইভেন্টোপথিথন
মার্ক বাইয়ার্স

1
return find_nth(s, x, n - 1, i + 1)হওয়া উচিত return find_nth(s, x, n - 1, i + len(x))। বড় কথা নয়, তবে কিছু গণনার সময় সাশ্রয় করে।
ড্যান লোয়েনেহার্জ

@ ডিএলও: বাস্তবে এটি কিছু ক্ষেত্রে বিভিন্ন ফলাফল দিতে পারে: find_nth ('আআআআআ', 'আ', ২)। খনি 1 দেয়, আপনার 2 দেয় I আমি অনুমান করি পোস্টারটি যা চায় তা আসলে yours আমি আমার কোড আপডেট করব। মন্তব্যের জন্য ধন্যবাদ.
মার্ক বাইয়ার্স

3

এটি আপনাকে মিলগুলির জন্য সূচক সূচনার একটি অ্যারে দেবে yourstring:

import re
indices = [s.start() for s in re.finditer(':', yourstring)]

তারপরে আপনার নবম প্রবেশটি হবে:

n = 2
nth_entry = indices[n-1]

অবশ্যই আপনাকে সূচকের সীমানা সম্পর্কে সতর্ক থাকতে হবে। আপনি এর yourstringমতো উদাহরণগুলির সংখ্যা পেতে পারেন :

num_instances = len(indices)

2

রেফাইন্ডার ব্যবহার করে এখানে আরেকটি পন্থা দেওয়া হয়েছে।
পার্থক্যটি হ'ল এটি কেবল যতটা প্রয়োজন খড়ের তীরে

from re import finditer
from itertools import dropwhile
needle='an'
haystack='bananabanana'
n=2
next(dropwhile(lambda x: x[0]<n, enumerate(re.finditer(needle,haystack))))[1].start() 

2

এখানে অন্য re+ itertoolsসংস্করণ রয়েছে যা একটি strবা একটি অনুসন্ধান করার সময় কাজ করা উচিত RegexpObject। আমি নির্দ্বিধায় স্বীকার করব যে এটি সম্ভবত অতিরিক্ত ইঞ্জিনিয়ারড, তবে কোনও কারণে এটি আমাকে বিনোদন দিয়েছে।

import itertools
import re

def find_nth(haystack, needle, n = 1):
    """
    Find the starting index of the nth occurrence of ``needle`` in \
    ``haystack``.

    If ``needle`` is a ``str``, this will perform an exact substring
    match; if it is a ``RegexpObject``, this will perform a regex
    search.

    If ``needle`` doesn't appear in ``haystack``, return ``-1``. If
    ``needle`` doesn't appear in ``haystack`` ``n`` times,
    return ``-1``.

    Arguments
    ---------
    * ``needle`` the substring (or a ``RegexpObject``) to find
    * ``haystack`` is a ``str``
    * an ``int`` indicating which occurrence to find; defaults to ``1``

    >>> find_nth("foo", "o", 1)
    1
    >>> find_nth("foo", "o", 2)
    2
    >>> find_nth("foo", "o", 3)
    -1
    >>> find_nth("foo", "b")
    -1
    >>> import re
    >>> either_o = re.compile("[oO]")
    >>> find_nth("foo", either_o, 1)
    1
    >>> find_nth("FOO", either_o, 1)
    1
    """
    if (hasattr(needle, 'finditer')):
        matches = needle.finditer(haystack)
    else:
        matches = re.finditer(re.escape(needle), haystack)
    start_here = itertools.dropwhile(lambda x: x[0] < n, enumerate(matches, 1))
    try:
        return next(start_here)[1].start()
    except StopIteration:
        return -1

2

Modle13 এর উত্তরে বিল্ডিং , তবে reমডিউল নির্ভরতা ছাড়াই ।

def iter_find(haystack, needle):
    return [i for i in range(0, len(haystack)) if haystack[i:].startswith(needle)]

আমি আশা করি এটি একটি বিল্টিন স্ট্রিং পদ্ধতি ছিল।

>>> iter_find("http://stackoverflow.com/questions/1883980/", '/')
[5, 6, 24, 34, 42]

1
>>> s="abcdefabcdefababcdef"
>>> j=0
>>> for n,i in enumerate(s):
...   if s[n:n+2] =="ab":
...     print n,i
...     j=j+1
...     if j==2: print "2nd occurence at index position: ",n
...
0 a
6 a
2nd occurence at index position:  6
12 a
14 a

1

অন্য একটি "কৌশল" সমাধান সরবরাহ করা হচ্ছে, যা ব্যবহার করে splitএবং join

আপনার উদাহরণে, আমরা ব্যবহার করতে পারি

len("substring".join([s for s in ori.split("substring")[:2]]))

1
# return -1 if nth substr (0-indexed) d.n.e, else return index
def find_nth(s, substr, n):
    i = 0
    while n >= 0:
        n -= 1
        i = s.find(substr, i + 1)
    return i

একটি ব্যাখ্যা দরকার
Ctznkane525

find_nth('aaa', 'a', 0)1এটি ফিরে আসা উচিত ফিরে 0। আপনার মতো কিছু দরকার i = s.find(substr, i) + 1এবং তারপরে ফিরে আসুন i - 1
a_guest

1

লুপ এবং পুনরাবৃত্তি ব্যবহার না করে সমাধান।

সংকলন পদ্ধতিতে প্রয়োজনীয় প্যাটার্নটি ব্যবহার করুন এবং ভেরিয়েবল 'n' এ কাঙ্ক্ষিত ঘটনাটি প্রবেশ করান এবং শেষ বিবৃতিটি প্রদত্ত স্ট্রিংয়ে প্যাটার্নের নবম উপস্থিতির সূচনা সূচক মুদ্রণ করবে। এখানে ফাইন্ডারের ফলাফল অর্থাৎ পুনরাবৃত্তিকে তালিকায় রূপান্তর করা হচ্ছে এবং সরাসরি নবম সূচকটি অ্যাক্সেস করা হচ্ছে।

import re
n=2
sampleString="this is history"
pattern=re.compile("is")
matches=pattern.finditer(sampleString)
print(list(matches)[n].span()[0])

1

যে বিশেষ ক্ষেত্রে আপনি কোনও চরিত্রের n'th উপস্থিতি অনুসন্ধান করেন (যেমন দৈর্ঘ্য 1 এর স্ট্রিং), নীচের ফাংশন প্রদত্ত চরিত্রের উপস্থিতিগুলির সমস্ত অবস্থানের একটি তালিকা তৈরি করে কাজ করে:

def find_char_nth(string, char, n):
    """Find the n'th occurence of a character within a string."""
    return [i for i, c in enumerate(string) if c == char][n-1]

nপ্রদত্ত চরিত্রটির উপস্থিতিগুলির চেয়ে কম যদি থাকে তবে তা দিবে IndexError: list index out of range

এটি @ জেডভি_ওডিডি এর উত্তর থেকে উদ্ভূত এবং একক চরিত্রের ক্ষেত্রে সরলিকৃত।



0

প্রতিস্থাপন ওয়ান লাইনার দুর্দান্ত তবে কেবলমাত্র কাজ করে কারণ এক্সএক্স এবং বারের একই লম্বা

একটি ভাল এবং সাধারণ ডিএফ হবে:

def findN(s,sub,N,replaceString="XXX"):
    return s.replace(sub,replaceString,N-1).find(sub) - (len(replaceString)-len(sub))*(N-1)

0

এটি সত্যই আপনি উত্তর চান:

def Find(String,ToFind,Occurence = 1):
index = 0 
count = 0
while index <= len(String):
    try:
        if String[index:index + len(ToFind)] == ToFind:
            count += 1
        if count == Occurence:
               return index
               break
        index += 1
    except IndexError:
        return False
        break
return False

0

এখানে খোঁজার জন্য আমার সমাধান nতম occurrance bস্ট্রিং a:

from functools import reduce


def findNth(a, b, n):
    return reduce(lambda x, y: -1 if y > x + 1 else a.find(b, x + 1), range(n), -1)

এটি খাঁটি পাইথন এবং পুনরুক্তিযোগ্য। 0 বা nএটি খুব বড়, এটি -1 প্রদান করে। এটি ওয়ান-লাইনার এবং সরাসরি ব্যবহার করা যেতে পারে। এখানে একটি উদাহরণ:

>>> reduce(lambda x, y: -1 if y > x + 1 else 'bibarbobaobaotang'.find('b', x + 1), range(4), -1)
7

0

def:

def get_first_N_words(mytext, mylen = 3):
    mylist = list(mytext.split())
    if len(mylist)>=mylen: return ' '.join(mylist[:mylen])

ব্যবহার করা:

get_first_N_words('  One Two Three Four ' , 3)

আউটপুট:

'One Two Three'

-2

কেমন:

c = os.getcwd().split('\\')
print '\\'.join(c[0:-2])

এটি প্রাথমিক প্রশ্নের উত্তর নয়
জেরজাইক

এটি প্রশ্নের উত্তর সরবরাহ করে না। আপনার যথেষ্ট খ্যাতি অর্জনের পরে আপনি কোনও পোস্টে মন্তব্য করতে সক্ষম হবেন ; পরিবর্তে, এমন উত্তরগুলি সরবরাহ করুন যা জিজ্ঞাসাবাদীর কাছ থেকে স্পষ্টতার প্রয়োজন হয় না
জেরজাইক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.