如何生成像列表理解这样的向量

Posted

技术标签:

【中文标题】如何生成像列表理解这样的向量【英文标题】:How to generate vector like list comprehension 【发布时间】:2016-07-20 06:27:06 【问题描述】:

在 C++11 中,

vector<string> blockPathList;
for(int i = 0; i < blockNum; i++)

    blockPathList.push_back(desPath + "part" + to_string(i));

是否可以像列表理解一样重写上面的代码,或者更短更简洁?

【问题讨论】:

blockNumdesPath 是什么? 看起来您正在将一种类型的列表(向量)转换为另一种。这似乎是 map 函数的工作,我相当确定 C++ 有。 @ChenZhongPu:我的意思是这些信息应该在您的问题中,以便可以适当地回答。阅读有关minimal reproducible example 的更多信息。 C++ 是否支持列表推导?您可能正在寻找 Haskell 或 Python 您是否对std::generate 感兴趣(尽管在这种情况下您需要预先设置矢量大小)? 【参考方案1】:

您想使用第三方库吗? Eric Niebler 的range-v3 允许:

std::vector<string> blockPathList =
        view::ints(0, blockNum)
        | view::transform([&desPath](int i) 
            return desPath + "part" + std::to_string(i);
        );

这与您将在 C++ 中获得的功能列表理解差不多。

【讨论】:

@Rotem OP 要求列表理解。 这是一个难以理解的列表理解,但她确实要求了。 请注意,range-v3 库将成为 C++20 标准的一部分。【参考方案2】:

也不漂亮,但也应该完成工作:

int cur = 0;
std::vector<std::string> blockPathList(blockNum);
std::generate(blockPathList.begin(), blockPathList.end(),
        [&]() return destPath + "part" + std::to_string(cur++); );

不幸的是

需要预先确定矢量大小 需要一个外部迭代变量(因为std::generate Generator 不接受任何参数。

你也可以使用std::for_each:

std::vector<int> nums(blockNum);
std::iota(nums.begin(), nums.end(), 0);
std::for_each(nums.begin(), nums.end(), [&](int c) 
        blockPathList.push_back(destPath + "part" + std::to_string(c));
        );

但这又是丑陋的,因为std::iota 不会生成范围。它使用迭代器填充现有范围,而不是本身充当数字迭代器(当然,您可以通过实现或使用生成这些迭代器的东西来解决这个问题)

【讨论】:

如果您使用generate_n (C++11) 和back_inserter,则不必预先设置矢量大小。【参考方案3】:

另一个例子(c++14):

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>

template<typename CONTAINER, typename LAMBDA>
auto comprehension(CONTAINER&& container, LAMBDA&& lambda)
      std::vector<decltype(lambda(*container.begin()))> w;
      std::transform(container.begin(),container.end(),std::back_inserter(w), lambda);
      return w;

int main()
    auto&& ints = 1,2,3,4,5;
    auto&& squares = comprehension(ints,[](auto i) return i*i; );

    for( auto s : squares) std::cout << s << ' '; 
    std::cout << '\n';

输出:

1 4 9 16 25

【讨论】:

以上是关于如何生成像列表理解这样的向量的主要内容,如果未能解决你的问题,请参考以下文章

如何动态生成用逗号分隔的类列表?

如何为排除的元素生成带有零的向量组合矩阵?

无限列表的 Haskell 笛卡尔积

我如何告诉 cmake 将解决方案和项目分开?

python 生成器理解

深入理解Python生成器(Generator)