Вставить некоторую строку в данную строку по указанному индексу в Python - PullRequest
54 голосов
/ 26 октября 2010

Я новичок в Python, столкнулся с проблемой: как вставить некоторые поля в уже существующую строку?

Например, предположим, что я прочитал одну строку из любого файла, который содержит:

line = "Name Age Group Class Profession"

Теперь мне нужно вставить 3-е поле (группу) в 3 раза больше в той же строке перед полем класса.Это означает, что строка вывода должна быть:

output_line = "Name Age Group Group Group Group Class Profession"

Я могу легко получить 3-е поле (используя метод split), но, пожалуйста, дайте мне знать, как проще всего вставить строку?

Ответы [ 8 ]

109 голосов
/ 26 октября 2010

Важным моментом, который часто кусает новых программистов на Python, но другие авторы не указали явно, является то, что строки в Python неизменны - вы не можете когда-либо изменять их на месте.

Вам нужно переучить себя при работе со строками в Python, чтобы вместо того, чтобы думать: «Как я могу изменить эту строку?»вместо этого вы думаете: «Как я могу создать новую строку, в которой есть несколько фрагментов из этой, которую я уже получил?»

85 голосов
/ 27 июня 2014

Ради будущих "новичков", решающих эту проблему, я думаю, что быстрый ответ подойдет для этой темы.

Как и bgporter сказал: строки Python неизменны, и поэтому, чтобы изменить строку, вы должны использовать части, которые у вас уже есть.

В следующем примере я вставляю 'Fu' в 'Kong Panda', чтобы создать 'Kong Fu Panda'

>>> line = 'Kong Panda'
>>> index = line.find('Panda')
>>> output_line = line[:index] + 'Fu ' + line[index:]
>>> output_line
'Kong Fu Panda'

В приведенном выше примере я использовал значение индекса, чтобы «разрезать» строку на 2 подстроки: 1 содержит подстроку перед индексом вставки, а другую содержит остальную часть. Затем я просто добавляю нужную строку между двумя и вуаля, мы вставили строку в другую.

Обозначение среза Python содержит отличный ответ, объясняющий тему среза строки.

13 голосов
/ 22 сентября 2014

Я знаю, что это неправильно, но ИМХО простой способ:

def insert (source_str, insert_str, pos):
    return source_str[:pos]+insert_str+source_str[pos:]
8 голосов
/ 26 октября 2010
line='Name Age Group Class Profession'
arr = line.split()
for i in range(3):
    arr.insert(2, arr[2])
print(' '.join(arr))
3 голосов
/ 25 декабря 2014

У меня была похожая проблема для моего назначения ДНК, и я воспользовался советом bgporter, чтобы ответить на него.Вот моя функция, которая создает новую строку ...

def insert_sequence(str1, str2, int):
    """ (str1, str2, int) -> str

    Return the DNA sequence obtained by inserting the 
    second DNA sequence into the first DNA sequence 
    at the given index.

    >>> insert_sequence('CCGG', 'AT', 2)
    CCATGG
    >>> insert_sequence('CCGG', 'AT', 3)
    CCGATG
    >>> insert_sequence('CCGG', 'AT', 4)
    CCGGAT
    >>> insert_sequence('CCGG', 'AT', 0)
    ATCCGG
    >>> insert_sequence('CCGGAATTGG', 'AT', 6)
    CCGGAAATTTGG

    """

    str1_split1 = str1[:int]
    str1_split2 = str1[int:]
    new_string = str1_split1 + str2 + str1_split2
    return new_string
3 голосов
/ 26 октября 2010

Есть несколько способов сделать это:

Один способ - использовать нарезку:

>>> a="line=Name Age Group Class Profession"
>>> b=a.split()
>>> b[2:2]=[b[2]]*3
>>> b
['line=Name', 'Age', 'Group', 'Group', 'Group', 'Group', 'Class', 'Profession']
>>> a=" ".join(b)
>>> a
'line=Name Age Group Group Group Group Class Profession'

Другой вариант - использовать регулярные выражения:

>>> import re
>>> a=re.sub(r"(\S+\s+\S+\s+)(\S+\s+)(.*)", r"\1\2\2\2\2\3", a)
>>> a
'line=Name Age Group Group Group Group Class Profession'
1 голос
/ 16 марта 2018

Осуществление

Приведенные ниже функции позволят вставить одну строку в другую строку:

def str_insert(from_me, into_me, at):
    """
    Inserts the string <from_me> into <into_me>

    Input <at> must be an integer index of <into_me> or a substring of <into_me>

    Inserts <from_me> AFTER <at>, not before <at>

    Inputs <from_me> and <into_me> must have working __str__ methods defined.
    This is satisfied if they already are strings.

    If not already strings, <from_me>, <into_me> are converted into strings.

    If you try to insert an empty string, that's fine, and the result
    is no different from the original.

    In order to insert 'from_me' after nothing (insert at the beginning of the string) use:
        at = ''  or  at = 0
    """
    try:
        return str_insert_or_raise(from_me, into_me, at)
    except ValueError as err:
        serr = str(err)
        if (str_insert_or_raise.__name__ in serr) and 'not found' in serr and '<at>' in serr:
            # if can't find where to insert stuff, don't bother to insert it
            # use str_insert_or_raise if you want an exception instead
            return into_me
        else:
            raise err

##############################################################

def str_insert_or_raise(from_me, into_me, at):
    """
    Inserts the string <from_me> into <into_me>

    Inserts <from_me> AFTER <at>, not before <at>

    Input <at> must be an integer index of <into_me> or a substring of <into_me>

    If <at> is the string '15', that substring will be searched for,
    '15' will not be interpreted as an index/subscript.        

    Inputs <from_me> and <into_me> must have working __str__ methods defined.
    If not already strings, <from_me>, <into_me> are converted into strings. 

    If you try to insert something, but we cannot find the position where
    you said to insert it, then an exception is thrown guaranteed to at least
    contain the following three substrings:
        str_insert_or_raise.__name__
        'not found'
        '<at>'
    """
    try:
        if isinstance(at, int):
            return str_insert_by_int(from_me, into_me, at)
        # Below, the calls to str() work fine if <at> and <from_me> are already strings
        # it makes them strings if they are not already
        return str_insert_by_str(str(from_me), str(into_me), str(at))
    except ValueError as err:
        serr = str(err)
        if 'empty string' in serr:
            return into_me # We allow insertion of the empty string
        elif ("<at>" in serr) and 'not found' in serr:
            msg_start = "In " + str_insert_or_raise.__name__ + ":  "
            msg = [msg_start, "\ninput ", "<at> string", " not found in ", "<into_me>",
                              "\ninput <",   str(at)  , "> not found in <", str(into_me), ">"]
            msg = ''.join(msg)
            raise ValueError(msg) from None
        else:
           raise err
#############################################################
def str_insert_by_str(from_me, into_me, at):
    """
    Inserts the string <from_me> into <into_me>

    puts 'from_me' AFTER 'at', not before 'at'
    For example,
        str_insert_or_raise(at = '2',  from_me = '0', into_me = '123')
    puts the zero after the 2, not before the 2
    The call returns '1203' not '1023'

    Throws exceptions if input arguments are not strings.

    Also, if <from_me> is empty or <at> is not a substring of <into_me> then
    an exception is raised.

    For fewer exceptions, use <str_insert_or_raise> instead.
    """
    try:
        s = into_me.replace(at, at + from_me, 1)
    except TypeError as terr: # inputs to replace are not strings
        msg_list = ['Inputs to function ', str_insert_by_str.__name__, '() must be strings']
        raise TypeError(''.join(msg_list)) from None
    # At the end of call to replace(), the '1'  indicates we will replace
    # the leftmost occurrence of <at>, instead of every occurrence of <at>
    if (s == into_me): # <at> string not found and/or <from_me> is the empty string
        msg_start = "In " + str_insert_by_str.__name__ + ":  "
        if from_me == '':
            msg = ''.join([msg_start, "attempted to insert an empty string"])
            raise ValueError(msg) from None
        raise ValueError(msg_start, "Input <at> string not found in <into_me>.",
                                    "\nUnable to determine where you want the substring inserted.") from None
    return s
##################################################
def str_insert_by_int(from_me, into_me, at):
    """
    * Inserts the string <from_me> into <into_me> at integer index <at>    
    * throws exceptions if input arguments are not strings.    
    * Also, throws an  exception if you try to insert the empty string    
    * If <at> is less than zero, <from_me> gets placed at the
      beginning of <into_me>    
    * If <at> is greater than the largest index of <into_me>,
      <from_me> gets placed after the end of <into_me>

    For fewer exceptions, use <str_insert_or_raise> instead.
    """
    at = into_me[:(at if at > 0 else 0)]
    return str_insert_by_str(from_me, into_me, at)

Использование

Приведенный ниже код демонстрирует, как вызвать функцию str_insert, заданную ранее

def foo(*args):
    return args

F = 'F. '

s = 'Using the string \'John \' to specify where to make the insertion'
result = str_insert(from_me = F, into_me ='John Kennedy', at ='John ')
print(foo('\n\n', s, '\n', result))

s = 'Using an int returned by find(\'Ken\') to specify where to make the insertion'
index = 'John Kennedy'.find('Ken') # returns the position of the first letter of 'Ken', not the last letter
result = str_insert(from_me = F, into_me ='John Kennedy', at = index)
print(foo('\n\n', s, '\n', result))

s = 'Using an int (5) to specify where to make the insertion.'
result = str_insert(from_me = F, into_me ='John Kennedy', at = 5)
print(foo('\n\n', s, '\n', result))

s = "Looking for an 'at' string which does not exist"
result = str_insert(from_me = F, into_me ='John Kennedy', at ='x')
print(foo('\n\n', s, '\n', result))

s = ''.join(["Looking for the empty string.",
             "\nFind one immediately at the beginning of the string"])
result = str_insert(from_me = F, into_me ='John Kennedy', at = '')
print(foo('\n\n', s, '\n', result))

s = "Insert an empty string at index 3. No visible change"
result = str_insert(from_me = '', into_me = 'John Kennedy', at = 3)
print(foo('\n\n', s, '\n', result))    

for index in [-5, -1, 0, 1, 997, 999]:
    s = "index " + str(index)
    result = str_insert(from_me = F, into_me = 'John Kennedy', at = index)
    print(foo('\n\n', s, '\n', result))

Предупреждение об отсутствии возможности изменить на месте

Ни одна из вышеперечисленных функций не изменит строку «на месте». Каждая из функций возвращает измененную копию строки, но исходная строка остается без изменений.

Например,

s = ''.join(["Below is what we get when we forget ",
             "to overwrite the string with the value",
             " returned by str_insert_or_raise:"])

examp_str = 'John Kennedy'
str_insert('John ', F, examp_str)
print(foo('\n\n', s, '\n', examp_str))

# examp_str is still 'John Kennedy' without the F
0 голосов
/ 06 ноября 2018

Ответ за Вставка символов строки в другие расположенные строки в расположениях

str1 = "ibuprofen"
str2 = "MEDICAL"
final_string=""
Value = 2
list2=[]
result=[str1[i:i+Value] for i in range(0, len(str1), Value)]
count = 0

for letter in result:
    if count < len(result)-1:
        final_string = letter + str2[count]
        list2.append(final_string)
    elif ((len(result)-1)==count):
        list2.append(letter + str2[count:len(str2)])
        break
    count += 1

print(''.join(list2))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...