4

Based on this I can create a homogeneous Python dictionary.

How can I create a dictionary with mixed-type values, e.g. make this work:

let dict = [ ("num", 8), ("str", "asd") ].into_py_dict(py);

?

tungli
  • 351
  • 1
  • 9

2 Answers2

7

I'm not a user of pyo3, but from Rust's point of view the problem is that you try to make a heterogeneous array, which is prohibited anyway. To solve it you may try to convert it into a homogeneous array by utilizing PyObject type of the crate. I can't test if the next snippet works and I'm not sure if you can make it simpler, but the idea holds:

let key_vals: &[(&str, PyObject)] = [ ("num", 8.to_object()), ("str", "asd".to_object()) ]
let dict = key_vals.into_py_dict(py);
Alexey S. Larionov
  • 6,555
  • 1
  • 18
  • 37
  • Might need some more conversion as `ToPyObject` returns a `type PyObject = Py`, but it's unclear that *that* implements `ToPyObject`, so you may need to get the `PyAny` out of the `Py` somehow. – Masklinn Nov 05 '20 at 13:09
  • Thanks! It seems that the idea works. This prints what I would expect: https://gist.github.com/tungli/e9afbb82abce2faf8de8635b37713e6a – tungli Nov 05 '20 at 14:07
5

Just for completion -- Alex Larionov's idea works!

The working code snippet is:

let key_vals: Vec<(&str, PyObject)> = vec![
    ("num", 8.to_object(py)), ("str", "asd".to_object(py))
];
let dict = key_vals.into_py_dict(py);

The whole main here.

This additional import is needed:

use pyo3::types::IntoPyDict;

Also, just a remark, if you happen to need to put a Python None value into the dictionary, where .to_object(py) fails, use:

py.None()

instead.

Variable py is the pyo3::Python object.

tungli
  • 351
  • 1
  • 9