6
$\begingroup$

Since Mathematica Associations are similar objects to python dictionaries I think there should be an easy way to export a Mathematica Associations such that it can easily be loaded into python as a dictionary.

How do I do this?

I generally see two methods. 1.) Export and import as JSON. 2.) Export as PythonExpression. With both I ran into issues. The issue I ran into with the second method is that the PythonExpression actually seems to contain an illegal python expression since it uses a list as a key where it should be using a tuple. I guess that the method of conversion depends a bit on the kind of structures that you want to export. In my case the Associations contain lists of real numbers as keys and Real numbers or lists of Real numbers as values. Converting the Real numbers to floats is fine since I do not require more precision.


Example of attempt:

Export[file, <|{0.52, 1.4} -> 5.1423545`|>, "PythonExpression"]

Creates a file with {[0.52, 1.4]: 5.1423545}. Reading it in python with

with open(file,"r") as f:
    data = ast.literal_eval(f.read())

Gives the error:

TypeError: unhashable type: 'list'
$\endgroup$
6
  • $\begingroup$ Perhaps you could include the specifications of the Python dictionaries target. I am unfamiliar with Python so I for one would be unable to grasp the problem as presented. $\endgroup$
    – MarcoB
    Jan 28 at 17:47
  • 3
    $\begingroup$ Right so in the example if we would have exported {(0.52, 1.4): 5.1423545} instead it would have worked because dictionaries can have tuples as key but not a list. I guess I can fix that easily with some string replacement. But I think I am asking for something that must have a better (and more standard) solution. So honestly I think it is more suitable if someone that can also see the pitfalls in importing the exported file into python answers this question. $\endgroup$
    – Kvothe
    Jan 28 at 17:51
  • $\begingroup$ Fair enough. Good luck then! $\endgroup$
    – MarcoB
    Jan 28 at 17:52
  • 1
    $\begingroup$ A considerate method based on string replacement should export list {{}, {0}, {1, 2}} as tuple ((), (0,), (1, 2)). $\endgroup$ Jan 28 at 18:51
  • 2
    $\begingroup$ I would export as WXF via BinarySerialize and then use the Wolfram client library for python to deserialize on the python side. $\endgroup$ Jan 28 at 20:44
6
$\begingroup$

Does it fit your needs?

Tuple;

Begin["ExternalEvaluatePython`Private`"];
encodeExprToPython[Tuple[]] = "()";
encodeExprToPython[Tuple[a_, b_ : ""]] :=  StringRiffle[{a, b}, {"(", ",", ")"}]
End[]
ExportString[<|Tuple[0.52, 1.4] -> 5.1423545`|>, "PythonExpression"]

{(0.52,1.4): 5.1423545}

$\endgroup$
5
  • $\begingroup$ Is there a way to transform an association with List keys to one with Tuple keys? Applying rule association/.{List->Tuple} does not affect the keys. And second question, can I easily define the Tuple for arbitrary number of arguments? $\endgroup$
    – OnDragi
    May 25 at 10:08
  • $\begingroup$ @OnDragi You can do KeyMap[If[ListQ@#.... . How should that general tuple be exported, here we have (1, ) for a single argument, notice the ,, so what input/output are we talking about here. $\endgroup$
    – Kuba
    May 25 at 14:48
  • $\begingroup$ Thank you for the quick answer! KeyMap works great. For the general tuple I meant triplets, quadruplets, etc., e.g., Tuple[1,2,3,4] being exported as (1,2,3,4). I figured that adding the following to your code works: encodeExprToPython[Tuple[a___]] := StringRiffle[{a}, {"(", ",", ")"}]. This one would almost work on its own too, it just wrongly translates one element list like {1} to (1) instead of the desired(1,), but that's the only case we need to deal with separately. Strangely though, I need to run the Begin[...];...;End[] block twice, otherwise it does not work. $\endgroup$
    – OnDragi
    May 25 at 16:48
  • $\begingroup$ @OnDragi you can define 3 rules, for Tuple[], Tuple[a_] and your Tuple[a___], in this order. And it should do fine. I don't know about Begin/End, make sure they are in separate lines, it can't be a single expression ( 1;2;3 is a single expression). $\endgroup$
    – Kuba
    May 26 at 3:39
  • $\begingroup$ The case Tuple[] is covered by Tuple[a___], so that isn't even necessary to define separately. Otherwise yes. I figured what was wrong with the "have to run twice" -- I did not include Tuple; before the block! So it wasn't about running the block more times, it was about running a cell that had Tuple in it. $\endgroup$
    – OnDragi
    May 26 at 14:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.