Python List of Dictionaries to C++

丶灬走出姿态 提交于 2020-01-23 21:38:25

问题


I have a Python list of dictionaries that I would like to translate to C++.

My list looks more or less like this:

myList = [{"v_A": 5, "v_B": 3}, {"v_A": 1, "v_B":2}, {"v_A":0, "v_B": 0}]

My code is designed such that when I look for e.g. velocities of particle 0, I do:

v = myList[0]["v_"+letter]

where letter would be a string, "A" or "B", depeding on the output of a sorting function I have. I have found this is the most convenient way to achieve my purpose in Python.

I am trying to translate my code to C++ (being a bit of a newbie) and I don't know how I could keep the "dictionary"-like features (that is, accessing values through a key that can be built concatenating strings) and the benefits the list together like in myList.

I read this question without much success, being unable to understand: C++ Equivalent of Python List of Dictionaries?

After some research, I thought of a using a vector of unordered maps, but I am unsure on how to define it and work with it. I thought of:

vector< unordered_map <string, int >> myList;

However, I am getting errors all the time. Besides, I don't know how to introduce the values in the dictionaries or access the elements. Am I approaching this from a completely wrong side?

EDIT: I found that if I define and insert the elements piece-wise, it seems to work:

std::vector <unordered_map <string, int> > myList;
unordered_map <string, int> tempMap;
tempMap.insert(std::make_pair("v_A", 10));
myList.push_back(tempMap);
cout << myList[0]["v_A"];

returns correctly 10. Is there a way to do this more efficient/ in a simpler way?


回答1:


std::vector<std::unordered_map<std::string, int>> dictList; // This is a list of dicts

std::unordered_map<std::string, int> dict; // Here we create a specific dict we want to add to our list of dicts

dict["key"] = 10; // This is how you add (key, value) pair into dict in c++

dictList.push_back(dict); // This is how you add your dict to the list of dicts



回答2:


Inserting in the list can be done much simpler.

At initialization you can do

std::vector<std::unordered_map<std::string, int>> myList {
    {{"v_A", 5}, {"v_B", 3}},
    {{"v_A", 1}, {"v_B", 2}},
    {{"v_A", 0}, {"v_B", 0}}
};

and you can later increase the size of the vector with push_back:

myList.push_back({{"v_A", 0}, {"v_B", 0}});

or you can add to a dictionary in one of the existing elements the same way as in python:

myList[0]["v_C"] = 12;

You cannot add elements to the vector this way though. (Accessing a vector out-of-bounds causes undefined behavior.)

Elements can be read as in Python with myList[0]["v_C"].

You cannot concatenate a character or C style string to a string literal directly with + as in v = myList[0]["v_"+letter] (depending on the type of letter it may compile but will probably not do what you expect it to do). But if you use

using namespace std::string_literals;

after the includes in your .cpp file, then you can write

v = myList[0]["v_"s+letter];

The s suffix then causes the string literal to be converted to a std::string, which provides a + operator that actually does concatenation.




回答3:


With a std::unordered_map you can use operator[] and if the element does not exist it will get inserted into the map.

This is not true for a vector. A vector is a dynamic array and you need to explicitly add elements to it before you can acces the already added elements with operator[].

std::vector<std::unordered_map<std::string, int>> myList;
myList[0]; // Invalid since the vector currently is empty.

myList.push_back({}); // Insert a default-constructed element in the vector

myList[0]; // Refers to the first element in the vector, which is a std::unordered_map<std::string, int>

myList[0]["string"] = 1; // This will create the elements if it does not already exist at mentioned above so this works fine

If you know the size you want you vector to have you can use std::vector::resize or a call to the constructor to set the size.

std::vector<std::unordered_map<std::string, int>> myList(10);
// Create a vector with 10 elements, so [0-9] would be in-bounds.

std::vector<std::unordered_map<std::string, int>> myList;
myList.resize(10); // This will do the same thing but in two steps.


来源:https://stackoverflow.com/questions/59499152/python-list-of-dictionaries-to-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!