Преобразовать данные из файла .TXT в формат YAML с помощью Python?

У меня есть огромный файл, содержащий данные, который выглядит следующим образом:

    H|Column1|Column2|Column3|
    T|2022-07-01|00001|TEST 1|
    T|2022-07-01|00002|TEST 2|
    F | Record count |    2| | 

Как мне создать следующее в формате YAML через Python?

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

Это должно выглядеть так:

H: T
Column1: 2022-07-01
Column2: 00001
Column3: TEST 1
-
 H: T
Column1: 2022-07-01
Column2: 00002
Column3: TEST 2

Приведите пример того, каким должен быть выходной формат YAML.

James 01.07.2024 16:04

Это больше похоже на файл значений, разделенных символами (CSV), чем на текстовый файл (TXT).

ndim 01.07.2024 16:05

Ваш «желаемый результат» не является допустимым YAML.

tripleee 01.07.2024 18:19

@triplee, как я уже сказал, я новичок в этом и прошу сообщество о помощи.

fl13 02.07.2024 07:45
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
4
67
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете использовать библиотеки csv и PyYAML для импорта значений, разделенных знаком «|», а затем выгрузить их в YAML.

Программы чтения CSV (DictReader и Reader) могут использовать любой символ в качестве разделителя. Это может быть запятая, табуляция или символ входных данных, трубка |.

DictReader считывает каждую строку CSV/TSV в объект словаря, где ключами являются имена столбцов, указанные в заголовке. Во входном файле есть пустое поле (| в конце), которое можно удалить. В значениях полей есть некоторые начальные/конечные пробелы, которые, возможно, не нужны, и их можно удалить.

С помощью объекта словаря можно сгенерировать YAML. PyYAML может выгружать поток словарей в один вывод YAML. Поэтому, если это большой файл, вы можете прочитать входной файл, обработать его и передать выходные данные в выходной файл построчно.

import csv
import io
import yaml


input_data = '''    H|Column1|Column2|Column3|
    T|2022-07-01|00001|TEST 1|
    T|2022-07-01|00002|TEST 2|
    F | Record count |    2| |
'''

def read_tsv(input_data):
    with io.StringIO(input_data) as f:
        cr = csv.DictReader(f, delimiter='|', skipinitialspace=True)
        for row in cr:
            del row['']
            for key, value in row.items():
                row[key] = value.strip()
            yield row

print(yaml.dump_all(read_tsv(input_data), sort_keys=False))

Вывод выглядит следующим образом:

H: T
Column1: '2022-07-01'
Column2: '00001'
Column3: TEST 1
---
H: T
Column1: '2022-07-01'
Column2: '00002'
Column3: TEST 2
---
H: F
Column1: Record count
Column2: '2'
Column3: ''

Немного отстойно, что PyYAML всегда записывает записи в алфавитном порядке. Некоторые другие библиотеки YAML предлагают большую гибкость.

tripleee 01.07.2024 18:21

@tripleee когда я проверил help(yaml), там есть параметр sort_keys для метода dump_all

r_2009 01.07.2024 18:28

Спасибо, давно мне не нужна была эта информация; приятно видеть, что все наконец изменилось!

tripleee 01.07.2024 18:30

Использование собственного Python без внешних библиотек,

def convert_to_yaml(data):
    lines = data.strip().split('\n')
    headers = lines[0].split('|')[:-1]
    rows = [line.split('|') for line in lines[1:]]
    
    yaml_text = ""
    for row in rows:
        for i, col_name in enumerate(headers):
            yaml_text += f"{col_name}: {row[i]}\n"
        yaml_text += "-\n"
    
    return yaml_text.strip('-\n')


data = """H|Column1|Column2|Column3|
T|2022-07-01|00001|TEST 1|
T|2022-07-01|00002|TEST 2|
F | Record count |    2| |"""

print(convert_to_yaml(data))

Ч: Т
Колонка 1: 01.07.2022
Столбец 2: 00001
Столбец 3: ТЕСТ 1
-
Ч: Т
Колонка 1: 01.07.2022
Столбец2: 00002
Столбец 3: ТЕСТ 2
-
Ч: Ф
Столбец 1: количество записей
Столбец2: 2
Столбец 3:

Одна из опасностей самостоятельного анализа заключается в том, что ваши результаты могут где-то вызвать нестандартный случай. Например, ведущие нули проблематичны; вы, вероятно, захотите поместить их в кавычки. YAML довольно громоздок и имеет множество подобных особенностей. Кроме того, одиночное тире в качестве разделителя неверно (хотя я думаю, что ОП виноват в предоставлении нежелательного желаемого результата).

tripleee 01.07.2024 18:16

Реальный вопрос: почему yaml? Кажется странным. Формат, который он хочет, неэффективен. Имена столбцов повторяются n-1 раз (где n — количество строк). Я бы предпочел использовать pandas для чтения файла и передачи "|" в качестве разделителя/разделителя. Чего бы он ни хотел добиться, я уверен, что преобразование в yaml в этом формате — не лучший способ.

trazoM 02.07.2024 10:17

@tripleee Я согласен, что в целом для дампа файлов лучше использовать библиотеку YAML, поскольку она проверяет необходимость кавычек (путем считывания выгруженного узла и проверки, является ли тип по-прежнему строкой). Но ведущие нули (множественные) создают проблемы только при работе с устаревшими библиотеками, поскольку YAML 1.2 ожидает 0o для восьмеричных чисел. Так что, по крайней мере, 00001 (без кавычек) в желаемом выводе ОП не имеет ничего плохого (другие вещи есть).

Anthon 03.07.2024 09:37

Другие вопросы по теме