Mu. You have started with the wrong premise.
Perl does not have a meaningful type system that distinguishes between numbers and strings. Any given value can be both. It can't be determined using only the Perl language whether a given value is considered to be a number only (although you can use modules like Devel::Peek
). It is utterly impossible to know what type a given value originally was.
my $x = 1; # an integer (IV), right?
say "x = $x"; # not any more! It's a PVIV now (string and integer)
Furthermore, in a hash map (“dictionary”), the key type is always coerced to a string. In arrays, the key is always coerced to an integer. Other types can only be faked.
This is wonderful when parsing text, but of course introduces endless pain when serializing a data structure. JSON maps perfectly to Perl data structures, so I suggest you stick to that (or YAML, as it is a superset of JSON) to protect yourself from the delusion that a serialization could infer information that isn't possibly there.
What do we take from this?
If interop is important, refrain from using creative dictionary types in Python.
You can always encode type information in the serialization should it really be important (hint: it probably isn't): {"type":"interger dict", "data":{"1":"foo","2":"bar"}}
It would also be premature to dismiss XML as too slow. See this recent article, although I disagree with the methods, and it restricts itself to JS (last week's HN thread for perspective).
If it is native, it will probably be fast enough, so obviously don't use any pure-Perl or pure-Python implementations. This also holds for JSON- and YAML- and whatnot -parsers.