Найти все индексы каждой буквы в строке - PullRequest
0 голосов
/ 18 февраля 2020

Я пытаюсь получить список, состоящий из индексов для каждого элемента другой последовательности. Звучит достаточно просто в теории.

a = 'string of letters'
b = [a.index(x) for x in a]

Но это не работает. Я пробовал списки, простые для циклов, с использованием enumerate et c, но каждый раз b будет возвращать один и тот же индекс для дубликатов в a. То есть 's' в a, например, вернет '0' в b как для первого, так и для последнего элемента, потому что они одного и того же символа. Я предполагаю, что это кеш или что-то в этом роде как способ для Python ускорить процесс.

В любом случае, я не могу понять это, и я был бы признателен за некоторую помощь в том, как я могу заставить это работать, а также, возможно, объяснение, почему это происходит.

Ответы [ 6 ]

2 голосов
/ 18 февраля 2020

Большое спасибо за ввод. Вообще-то, я понял это с помощью enumerate. Чтобы уточнить, у меня было два списка, а и б. a содержит как прописные, так и строчные буквы. b состоит из тех же символов, что и a, но сдвинутых на определенное количество позиций, как в шифре. Я хотел сохранить регистр символов в b в той же позиции после «кодирования», но мне нужен был индекс каждого символа в «A».

В любом случае, все было так просто:

a = 'tEXt'
c = [x for x,y in enumerate(a) if y.isupper()]
b = ['x', 't', 't', 'e'] #(this is the encoded version of 'a', returned from a different place as a string, but converted here to a list)
for x in c:
  b[x] = b[x].upper()
b = ''.join[b]
b 
  'xTTe'
2 голосов
/ 18 февраля 2020

.index просто возвращает первое вхождение символа в строку - это не имеет никакого отношения к кэшам. Похоже, вы просто хотите получить список чисел от 0 до длины строки-1:

b = list(range(len(a)))

Вы не упоминаете, зачем вам это нужно, но довольно редко нужно что-то подобное в Python , Заметка в Python 3 range возвращает собственный специальный тип, представляющий неизменяемую последовательность чисел, поэтому вам нужно явно преобразовать его в список, если вам это действительно нужно.

1 голос
/ 19 февраля 2020

Я изменил код, который вы отправили как ответ, дайте мне знать, правильно ли я все понял.

from typing import List


def copy_case(a: str, b: str) -> str:
    res_chars: List[str] = []
    curr_a: str
    curr_b: str

    for curr_a, curr_b in zip(a, b):
        if curr_a.isupper():
            curr_b = curr_b.upper()
        else:
            curr_b = curr_b.lower()
        res_chars.append(curr_b)

    return ''.join(res_chars)


print(copy_case('tEXt', 'xTTe'))
0 голосов
/ 18 февраля 2020

Для этой цели, вероятно, лучше использовать dict:

foo = {x : [] for x in a}   #creates dict with keys being unique values in a
for i,x in enumerate(a):
    foo[x].append(i)        #adds each index into dict

, например, для строки 'abababababa':

{'a': [0, 2, 4, 6, 8], 'b': [1, 3, 5, 7, 9]} 
0 голосов
/ 18 февраля 2020

Звучит так, будто вы пытаетесь получить список значений каждого входного символа в качестве вывода. Таким образом, для s вы получите [0, 16] или что-то в этом роде.

Таким образом, для каждого входного символа вы добавляете его позицию в правильный список.

Сохранение результатов в формате dict кажется хорошим подходом, поэтому что-то вроде:

def index_dict(stringy):
    d = {}
    for index, char in enumerate(stringy):
        if char not in d:
            d[char] = []
        d[char].append(index)
    return d

Метод index() всегда находит первое вхождение. Вам нужно найти все вхождения. Итак, вышеприведенное удовольствие c даст вам подсказку, что все ключи соответствуют символам вашей входной строки, а затем значение для каждой клавиши представляет собой список значений, где находится этот символ.

0 голосов
/ 18 февраля 2020

Одним из подходов может быть создание словаря, итерация по разным буквам в строке и использование re.finditer для получения индекса всех вхождений в строке. Итак, шаг за шагом:

import re
a = 'string of letters'

Мы можем найти уникальные буквы в строке, взяв набор:

letters = set(a.replace(' ',''))
# {'e', 'f', 'g', 'i', 'l', 'n', 'o', 'r', 's', 't'}

Затем мы можем использовать словарное понимание для построения словаря, в котором значения являются списком, сгенерированным путем итерации по всем экземплярам совпадений, возвращаемым re.finditer:

{w: [m.start() for m in re.finditer(w, a)] for w in letters}

{'i': [3],
 'o': [7],
 'f': [8],
 'l': [10],
 'g': [5],
 'e': [11, 14],
 't': [1, 12, 13],
 's': [0, 16],
 'n': [4],
 'r': [2, 15]}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...