Прерывание станд.:: цикл for_each

После нескольких других опций подпроцесс, казалось, работал достаточно хорошо. Вы можете запустить R-скрипт из Python через подпроцесс и предоставить значение функции в качестве аргумента (x):

def R_script_runner(x):
    import subprocess
    output=subprocess.run(
            ["your_path_to_R_source_folder/Rscript.exe",  "your_path_to_R_script/R_script.R", x], 
                                  shell=True, stdin=subprocess.PIPE,
                                  stdout=subprocess.PIPE,
                                  stderr=subprocess.PIPE).stderr 
    return output  

R-скрипт сделает то, что должен. Вывод возвращается функцией в основном для отладки, так что вы можете распечатать ее или оценить иначе.

26
задан Naveen 17 April 2009 в 12:30
поделиться

6 ответов

Вы можете использовать алгоритм find_if, который остановит и вернет итератор, где условие предиката, примененное к итерированному элементу, возвращает true , Таким образом, ваш предикат должен быть изменен, чтобы он возвращал логическое значение в качестве условия продолжения / прерывания.

Однако, это хак, поэтому вы можете использовать алгоритмы.

Другой способ - использовать BOOST_FOREACH.

13
ответ дан 28 November 2019 в 06:42
поделиться

Если вы хотите выполнить какие-то действия, когда условие не выполняется, возможно, вам нужно изменить алгоритм на что-то вроде std :: find_if ?

6
ответ дан 28 November 2019 в 06:42
поделиться

Как уже показали другие, это возможно только с обходными путями, которые ИМХО запутывают код.

Так что мои предложения изменить for_each в обычный цикл for. Это сделает более видимым для других, что вы используете break (и, возможно, даже продолжаете).

4
ответ дан 28 November 2019 в 06:42
поделиться

Вы не можете сделать это, если не выбросите исключение, что не очень хорошая идея, потому что вы этого не делаете управляйте потоком с исключениями.

Обновление: очевидно, Boost имеет for_each_if, который может помочь , но вы не используете Boost.

2
ответ дан 28 November 2019 в 06:42
поделиться

Вы выбросили исключение. Является ли это хорошей идеей, это своего рода вопрос стиля, темп @Dan, но может быть больше проблемы с вашим дизайном. for_each предназначен для своего рода стиля функционального программирования, который неявно предполагает, что ваша функция может применяться равномерно по всему набору. Итак, если вам нужно сделать разрыв, это может рассматриваться как необычное условие и, следовательно, достойное исключения.

Другое решение, и более «функциональное» решение, заключается в написании вашей функции. так что, если это не должно влиять на некоторые приложения, напишите это, чтобы не иметь никакого эффекта. Так, например, если у вас была функция суммирования, добавьте 0 в случаях, из которых вы бы «сломались».

0
ответ дан 28 November 2019 в 06:42
поделиться

Вы можете выйти из for_each (), вызвав исключение из вашего функтора. Однако это часто не очень хорошая идея, и есть альтернативы.

Вы можете сохранить состояние в своем функторе. Если вы обнаружите состояние «перерыв», просто установите флаг в вашем функторе, а затем для каждой последующей итерации просто возвращайтесь, не выполняя действия вашего функтора. Очевидно, это не остановит итерацию, которая может быть дорогой для больших коллекций, но, по крайней мере, остановит выполнение работы.

Если ваша коллекция отсортирована, вы можете найти () элемент, который хотите разбить. at, затем выполните for_each от begin () до возвращаемого элемента find ().

Наконец, вы можете реализовать for_each_if () . Это снова не остановит итерацию, но не оценит ваш функтор, который выполняет работу, если предикат оценивается как ложный. Вот два варианта for_each_xxx () , один из которых принимает значение и выполняет работу, если оператор == () оценивается как true, а другой - два функтора; тот, который выполняет сравнение аля find_if (), и другой, который выполняет работу, если оператор сравнения оценивается как true.

/* ---

    For each
    25.1.1

        template< class InputIterator, class Function, class T>
            Function for_each_equal(InputIterator first, InputIterator last, const T& value, Function f)

        template< class InputIterator, class Function, class Predicate >
            Function for_each_if(InputIterator first, InputIterator last, Predicate pred, Function f)

    Requires:   

        T is of type EqualityComparable (20.1.1) 

    Effects:    

         Applies f to each dereferenced iterator i in the range [first, last) where one of the following conditions hold:

            1:  *i == value
            2:  pred(*i) != false

    Returns:    

        f

    Complexity: 

        At most last - first applications of f

    --- */

    template< class InputIterator, class Function, class Predicate >
    Function for_each_if(InputIterator first, 
                         InputIterator last, 
                         Predicate pred, 
                         Function f)
    {
        for( ; first != last; ++first)
        {
            if( pred(*first) )
                f(*first);
        }
        return f;
    };

    template< class InputIterator, class Function, class T>
    Function for_each_equal(InputIterator first, 
                            InputIterator last, 
                            const T& value, 
                            Function f)
    {
        for( ; first != last; ++first)
        {
            if( *first == value )
                f(*first);
        }
        return f;
    };
14
ответ дан 28 November 2019 в 06:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: