2016-06-28 2 views
0

Для создания Tecplot файла я использую:Написать Python отформатированного генератора

import numpy as np 

x, y = np.genfromtxt('./files.dat', unpack=True) 
nb_value = x.size 
x_splitted = np.split(x, nb_value // 1000 + 1) 
y_splitted = np.split(y, nb_value // 1000 + 1) 

with open('./test.dat', 'w') as f: 
    f.write('TITLE = \" YOUPI \" \n') 
    f.write('VARIABLES = \"x\" \"Y\" \n') 
    f.write('ZONE T = \"zone1 \" , I=' + str(nb_value) + ', F=BLOCK \n') 
    for idx in range(len(x_splitted)): 
     string_list = ["%.7E" % val for val in x_splitted[idx]] 
     f.write('\t'.join(string_list)+'\n') 
    for idx in range(len(y_splitted)): 
     string_list = ["%.7E" % val for val in y_splitted[idx]] 
     f.write('\t'.join(string_list)+'\n') 

Вот пример file.dat:

-6.491083147394967334e-02 6.917197804459292456e+02 
-6.489978349202699115e-02 6.871829941905543819e+02 
-6.481115367048655151e-02 6.707292800160890920e+02 
-6.479991205404790622e-02 6.756112033303363660e+02 
-6.471117816968344205e-02 7.666798999627604871e+02 
-6.469995628177811764e-02 7.819675271405360490e+02 

Этот код работает, но я видел, что я должен используйте .format() вместо %. Это работает: string_list = ["{}".format(list(val for val in y_splitted[idx]))], но не будет работать с Tecplot, потому что нам нужно 7E.

Если я попробую: string_list = ["{.7E}".format(list(val for val in y_splitted[idx]))], он вообще не работает. Я получил: AttributeError: 'list' object has no attribute '7E'

Что было бы лучшим способом сделать то, что я пытаюсь сделать?

+0

@freakish: выглядит, как вы поняли, что '% .7E' делает в операции форматирования строки. –

ответ

2

Форматирование спецификаторы приходят после : толстой кишки:

["{:.7E}".format(val) for val in y_splitted[idx]] 

Следует заметить, что я должен был настроить свой список понимание синтаксиса, а также; вы только хотите применить каждый val до str.format(), а не весь цикл. По сути, вам нужно было только заменить часть "%.7E" % val.

Смотрите Format String Syntax documentation:

replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}" 

Демо:

>>> ["%.7E" % val for val in (2.8, 4.2e5)] 
['2.8000000E+00', '4.2000000E+05'] 
>>> ["{:.7E}".format(val) for val in (2.8, 4.2e5)] 
['2.8000000E+00', '4.2000000E+05'] 

Не то, что вам действительно нужно использовать str.format() поскольку там нет других частей строки; если все у вас есть "{:<formatspec>}", просто использовать format() function и передать в <formatspec> в качестве второго аргумента:

[format(val, ".7E") for val in y_splitted[idx]] 

Обратите внимание, что в Python, вы вообще не перебирает range() затем использовать индекс, чтобы получить список стоимость. Просто цикл по списку непосредственно:

for xsplit in x_splitted: 
    string_list = [format(val, ".7E") for val in xsplit] 
    f.write('\t'.join(string_list) + '\n') 
for ysplit in y_splitted: 
    string_list = [format(val, ".7E") for val in ysplit] 
    f.write('\t'.join(string_list)+'\n') 

Вы также не должны избежать " символов в ваших строках; вам нужно только сделать это, когда строковые разделители также являются " символами; вместо этого вы используете '. Вы можете использовать str.format() вставить nb_value там:

f.write('TITLE = " YOUPI " \n') 
f.write('VARIABLES = "x" "Y" \n') 
f.write('ZONE T = "zone1 " , I={}, F=BLOCK \n'.format(nb_value)) 
+0

Большое спасибо Martijn! Очень ясный и поучительный ответ. Последнее, кто-то рассказал мне о 'map' для строкового листинга, поскольку он более эффективен, но я не вижу, как использовать спецификатор здесь:' map (str (format = '%. 7e', ??),? ?) ' – Y0da

+0

@ Y0da; вы не можете использовать 'map()' здесь; использование перечня - лучший вариант. –

+0

Спасибо, что у вас есть :) – Y0da

Смежные вопросы