Запись списка комплексных чисел в виде двоичных данных

#python

#python

Вопрос:

Я пытаюсь вывести некоторые данные из скрипта Python в двоичный файл.

Если у меня есть список с плавающей точкой, я использую это

 out_file = open("filename", "wb")
float_array.array("f", [])
float_array.fromlist(mylist)
float_array.tofile(out_file)
out_file.close()
  

Кажется, это работает нормально, по крайней мере, в результате получается файл с правильным количеством байт.

Как я могу сделать то же самое, но используя список комплексных чисел?

Спасибо

Комментарии:

1. Для комплексных чисел не существует стандартного двоичного представления (по крайней мере, насколько мне известно), поэтому сначала вам нужно решить, как вы хотите, чтобы они были представлены.

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

Ответ №1:

Не изобретайте свои собственные методы сериализации, когда Python предлагает так много хороших готовых методов! Я предлагаю вам использовать pickle — он также работает с комплексными числами (*):

 >>> import pickle
>>> s = pickle.dumps([1 2j, 5-1j])
>>> pickle.loads(s)
[(1 2j), (5-1j)]
  

Я использую dumps здесь для демонстрации, вы также можете использовать dump который записывает в двоичный файл.


(*) Из документа pickle:

Могут быть выбраны следующие типы:

  • Нет, True и False
  • целые числа, длинные целые числа, числа с плавающей запятой, комплексные числа
  • обычные строки и строки в Юникоде
  • кортежи, списки, наборы и словари, содержащие только выделяемые объекты
  • функции, определенные на верхнем уровне модуля
  • встроенные функции, определенные на верхнем уровне модуля
  • классы, которые определены на верхнем уровне модуля
  • экземпляры таких классов, __dict__ or __setstate__() которых можно выбирать (подробности см. в разделе Протокол pickle *)

Комментарии:

1. Помните о демпинге при записи файла pickle для использования двоичного режима 😉

2. Спасибо, я не уверен, что это сработает. Кажется, что записывается намного больше данных, чем я ожидаю. Мне нужно иметь возможность считывать эти данные из кода C, поэтому мне нужны необработанные двоичные данные.

3. @rvabdn: Python cPickle реализован на C, вы, вероятно, могли бы заставить его работать из C-кода. Возможно, это все слишком сложно для ваших нужд, но я просто оставляю это как предложение

Ответ №2:

Вы могли бы создать из вашего сложного массива сплющенный список с плавающей точкой, например

 flattend = [f for sublist in ((c.real, c.imag) for c in complex_list) for f in sublist]
  

и запишите это в файл.

Комментарии:

1. Это маршрут, по которому я пошел в конце.