簡體   English   中英

如何在字符串中查找字符並獲取所有索引?

[英]How to find char in string and get all the indexes?

我得到了一些簡單的代碼:

def find(str, ch):
    for ltr in str:
        if ltr == ch:
            return str.index(ltr)
find("ooottat", "o")

該函數只返回第一個索引。 如果我改變 return 打印,它會打印 0 0 0。為什么會這樣,有什么辦法可以得到0 1 2

這是因為str.index(ch)將返回ch第一次出現的索引。 嘗試:

def find(s, ch):
    return [i for i, ltr in enumerate(s) if ltr == ch]

這將返回您需要的所有索引的列表。

PS Hugh 的回答顯示了一個生成器函數(如果索引列表變大會有所不同)。 也可以通過將[]更改為()來調整此功能。

我會和 Lev 一起去,但值得指出的是,如果你最終得到更復雜的搜索,那么使用 re.finditer 可能值得牢記(但 re 通常會造成比價值更多的麻煩 - 但有時很容易知道)

test = "ooottat"
[ (i.start(), i.end()) for i in re.finditer('o', test)]
# [(0, 1), (1, 2), (2, 3)]

[ (i.start(), i.end()) for i in re.finditer('o+', test)]
# [(0, 3)]

Lev 的答案是我會使用的答案,但是這里有一些基於您的原始代碼的內容:

def find(str, ch):
    for i, ltr in enumerate(str):
        if ltr == ch:
            yield i

>>> list(find("ooottat", "o"))
[0, 1, 2]
def find_offsets(haystack, needle):
    """
    Find the start of all (possibly-overlapping) instances of needle in haystack
    """
    offs = -1
    while True:
        offs = haystack.find(needle, offs+1)
        if offs == -1:
            break
        else:
            yield offs

for offs in find_offsets("ooottat", "o"):
    print offs

結果是

0
1
2
def find_idx(str, ch):
    yield [i for i, c in enumerate(str) if c == ch]

for idx in find_idx('babak karchini is a beginner in python ', 'i'):
    print(idx)

輸出:

[11, 13, 15, 23, 29]
x = "abcdabcdabcd"
print(x)
l = -1
while True:
    l = x.find("a", l+1)
    if l == -1:
        break
    print(l)

根據經驗,NumPy 數組在處理 POD、Plain Old Data 時通常優於其他解決方案。 字符串也是 POD 和字符的一個例子。 要查找字符串中僅一個字符的所有索引,NumPy ndarrays 可能是最快的方法:

def find1(str, ch):
  # 0.100 seconds for 1MB str 
  npbuf = np.frombuffer(str, dtype=np.uint8) # Reinterpret str as a char buffer
  return np.where(npbuf == ord(ch))          # Find indices with numpy

def find2(str, ch):
  # 0.920 seconds for 1MB str 
  return [i for i, c in enumerate(str) if c == ch] # Find indices with python

在一行中獲取所有位置

word = 'Hello'
to_find = 'l'

# in one line
print([i for i, x in enumerate(word) if x == to_find])

使用pandas我們可以這樣做並返回帶有所有索引的dict,簡單版本:

import pandas as pd

d = (pd.Series(l)
     .reset_index()
     .groupby(0)['index']
     .apply(list)
     .to_dict())

但我們也可以建立條件,例如,只有兩個或更多的出現:

d = (pd.Series(l)
     .reset_index()
     .groupby(0)['index']
     .apply(lambda x: list(x) if len(list(x)) > 1 else None)
     .dropna()
     .to_dict())

這是Mark Ransom答案的略微修改版本,如果ch長度可能超過一個字符,則該答案有效。

def find(term, ch):
    """Find all places with ch in str
    """
    for i in range(len(term)):
        if term[i:i + len(ch)] == ch:
            yield i

所有其他答案都有兩個主要缺陷:

  1. 他們通過字符串執行 Python 循環,這非常慢,或者
  2. 他們使用 numpy,這是一個非常大的附加依賴項。
def findall(haystack, needle):
    idx = -1
    while True:
        idx = haystack.find(needle, idx+1)
        if idx == -1:
            break
        yield idx

這會在haystack迭代尋找needle ,總是從上一次迭代結束的地方開始。 它使用內置的str.find ,這比逐字符迭代haystack快得多。 它不需要任何新的進口。

為了修飾@Lev 和@Darkstar 發布的五星級單線:

word = 'Hello'
to_find = 'l'
print(", ".join([str(i) for i, x in enumerate(word) if x == to_find]))

這只是使索引號的分離更加明顯。
結果將是: 2, 3

你可以試試這個

def find(ch,string1):
    for i in range(len(string1)):
        if ch == string1[i]:
            pos.append(i)        

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM