2015-01-18 3 views
0

Я генерирую sql-запрос и выполняю много операций + = на моей строке. Это выглядит так:Как получить изменяемую строку?

insert_string = 'INSERT INTO ' + table_name + ' VALUES ' 
for row in data_frame.iterrows(): 
     raw_row = row[1].values 
     insert_string += str(tuple(raw_row)) 

Так что если моя insert_string неизменяема, каждая операция + = создает новую строку. Например, в C# для этого класса StringBuilder, который может инициализировать пустую строку с заданной емкостью. Как я могу это сделать в Python?

+3

Примечание - Вы не хотите, чтобы этот подход ... это подвергается атакам SQL-инъекции. Библиотеки Python имеют стандартный API DBI, который позволяет безопасно строить строку запроса - см. Http://stackoverflow.com/questions/11807601/what-is-the-most-effective-way-of-inserting-python-dictionaries- list-in-sql/11807972 # 11807972 например –

ответ

5

Пожалуй, самые распространенный способом является созданием списка всех частей, и присоединиться к ним с помощью метода str.join, как это:

pieces = ['a', 'b', 'c'] 
text = ''.join(pieces) 
assert text == 'abc' 

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

pieces = ['a', 'b', 'c'] 
text = '\n'.join(pieces) 

Кроме того, вы можете получить файловый интерфейс, как с помощью io.StringIO класса :

with io.StringIO() as query_str: 
    query_str.write('INSERT INTO ') 
    query_str.write(table_name) 
    query_str.write(' VALUES ') 
    for row in data_frame.iterrows(): 
     raw_row = row[1].values 
     query_str.write(str(tuple(raw_row))) 
    # Use query_str.getvalue(), as it will be deleted 
    # when the 'with' scope is finished. 
1

В Python 2 имеется модуль под названием UserString, который содержит MutableString.

from UserString import * 

myString = MutableString('String') 
myString.pop(0) 
myString[1] = 'h' 
print myString # prints 'thing' 
+1

Этот класс устарел в 2.6 и не существует в 3.x. Существует обсуждение этого [здесь] (http://stackoverflow.com/questions/4651344/why-is-mutablestring-deprecated-in-python) –

+0

Действительно, я использую его в 2.7.8. –

+1

Устаревание не означает, что он был удален, это означает, что он не должен использоваться в новом коде и, вероятно, будет удален в будущем. –

1

, что вы, вероятно, ищете это StringIO, который представляет собой файл-подобный интерфейс для списка строк, и позволяет извлечь одну строку в конце:

import StringIO 

builder = StringIO.StringIO() 
builder.write('INSERT INTO ') 
builder.write(table_name) 
builder.write(' VALUES ') 
for row in data_frame.iterrows(): 
     raw_row = row[1].values 
     builder.write(str(tuple(raw_row))) 
insert_string = builder.getvalue() 

Хотя большинство пользователей python довольны использованием списка напрямую, как в Rafael's answer. Для полноты вот ваш код переводится в этот стиль:

builder = ['INSERT INTO ', table_name, ' VALUES '] 
for row in data_frame.iterrows(): 
     raw_row = row[1].values 
     builder.append(str(tuple(raw_row))) 
insert_string = ''.join(builder) 

В нечетном случае, что кто-просмотр на этот вопрос на самом деле нуждается в изменяемую строке; Мне жаль говорить, что нет ничего такого, и решение зависит от конкретной проблемы, которую вы пытаетесь решить. Если вам нужна переменная байт, это доступно, встроенное, как bytearray.

>>> b 
bytearray(b'xaby') 
>>> b[1:3] = b'yz' 
>>> b 
bytearray(b'xyzy') 
>>> b.extend(b'foonly') 
>>> b 
bytearray(b'xyzyfoonly') 

нет эквивалентного действия для str.

1

Вот хорошая статья о Efficient String Concatenation in Python, которая очень подходит для вашей проблемы.

TL; др: Использование join со списком понимания:

''.join([str(tuple(row[1].values)) for row in data_frame.iterrows()])