String cut by a separator with the separator in the respective list element in python

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
3
down vote

favorite
1












Python 3.6.5



Is there any better solution than this one? Particularly the last line. I don't like it.



import re
s = "my_separator first thing my_separator second thing"
data = re.split("(my_separator )", s)[1:]
data = [even+odd for i, odd in enumerate(data) for j, even in enumerate(data) if i%2==1 and j%2==0 and i==j+1]






share|improve this question















  • 3




    No need for regex at all. str.split can accept string separator.
    – hjpotter92
    May 15 at 11:29










  • @hjpotter92 it can however I don't know how to call it to keep the separator. It removes it from the results however if you enclose re.split expression in a group (()) it keeps the separators in the results (but puts them separately from the results).
    – VaNa
    May 15 at 15:07
















up vote
3
down vote

favorite
1












Python 3.6.5



Is there any better solution than this one? Particularly the last line. I don't like it.



import re
s = "my_separator first thing my_separator second thing"
data = re.split("(my_separator )", s)[1:]
data = [even+odd for i, odd in enumerate(data) for j, even in enumerate(data) if i%2==1 and j%2==0 and i==j+1]






share|improve this question















  • 3




    No need for regex at all. str.split can accept string separator.
    – hjpotter92
    May 15 at 11:29










  • @hjpotter92 it can however I don't know how to call it to keep the separator. It removes it from the results however if you enclose re.split expression in a group (()) it keeps the separators in the results (but puts them separately from the results).
    – VaNa
    May 15 at 15:07












up vote
3
down vote

favorite
1









up vote
3
down vote

favorite
1






1





Python 3.6.5



Is there any better solution than this one? Particularly the last line. I don't like it.



import re
s = "my_separator first thing my_separator second thing"
data = re.split("(my_separator )", s)[1:]
data = [even+odd for i, odd in enumerate(data) for j, even in enumerate(data) if i%2==1 and j%2==0 and i==j+1]






share|improve this question











Python 3.6.5



Is there any better solution than this one? Particularly the last line. I don't like it.



import re
s = "my_separator first thing my_separator second thing"
data = re.split("(my_separator )", s)[1:]
data = [even+odd for i, odd in enumerate(data) for j, even in enumerate(data) if i%2==1 and j%2==0 and i==j+1]








share|improve this question










share|improve this question




share|improve this question









asked May 15 at 10:59









VaNa

214




214







  • 3




    No need for regex at all. str.split can accept string separator.
    – hjpotter92
    May 15 at 11:29










  • @hjpotter92 it can however I don't know how to call it to keep the separator. It removes it from the results however if you enclose re.split expression in a group (()) it keeps the separators in the results (but puts them separately from the results).
    – VaNa
    May 15 at 15:07












  • 3




    No need for regex at all. str.split can accept string separator.
    – hjpotter92
    May 15 at 11:29










  • @hjpotter92 it can however I don't know how to call it to keep the separator. It removes it from the results however if you enclose re.split expression in a group (()) it keeps the separators in the results (but puts them separately from the results).
    – VaNa
    May 15 at 15:07







3




3




No need for regex at all. str.split can accept string separator.
– hjpotter92
May 15 at 11:29




No need for regex at all. str.split can accept string separator.
– hjpotter92
May 15 at 11:29












@hjpotter92 it can however I don't know how to call it to keep the separator. It removes it from the results however if you enclose re.split expression in a group (()) it keeps the separators in the results (but puts them separately from the results).
– VaNa
May 15 at 15:07




@hjpotter92 it can however I don't know how to call it to keep the separator. It removes it from the results however if you enclose re.split expression in a group (()) it keeps the separators in the results (but puts them separately from the results).
– VaNa
May 15 at 15:07










4 Answers
4






active

oldest

votes

















up vote
1
down vote



accepted










hjpotters92’s answer is great for fixed separator strings. If the separators vary and one wants to join them with each subsequent match one can use the following two approaches, neither of which requires closures:



1 Generator function



def split_with_separator1(s, sep):
tokens = iter(re.split(sep, s))
next(tokens)
while True:
yield next(tokens) + next(tokens)


The expression inside the loop works because the Python language guarantees left-to-right evaluation (unlike many other languages, e. g. C).



2 Interleaved slices and binary map



import operator

def split_with_separator2(s, sep)
tokens = re.split(sep, s)
return map(operator.add, tokens[1::2], tokens[2::2])


Of course one can slice with itertools.islice instead if one doesn't want to create two ephemeral token list copies.






share|improve this answer




























    up vote
    8
    down vote













    You can exploit zip and iterators to allow you to pair things together:



    data = [a + b for a, b in zip(*[iter(data)]*2)]



    You could use just re, and change the separator with a look ahead assertion.



    data = re.split(" (?=my_separator)", s)



    You can use str.split, and just add the separator back:



    sep = 'my_separator '
    data = s.split(sep)[1:]
    data = [sep + i for i in data]




    data = [sep + i for i in s.split(sep)]





    share|improve this answer























    • Didn't know about itertools recipes, thanks a lot! I consider the lookahead most elegant as I won't have to process it then.
      – VaNa
      May 15 at 14:31











    • The lookahead is not as general as I thought because split has to consume something and that something has to precede the separator :-( pairwise it is!
      – VaNa
      May 15 at 14:46











    • pairwise cuts it as (1,2),(2,3),(3,4),..., my code does (1,2),(3,4),....
      – VaNa
      May 15 at 15:15







    • 1




      @VaNa My bad, yes, I've fixed that
      – Peilonrayz
      May 15 at 15:19






    • 2




      @VaNa: The lookahead works fine, just not in Python. :-/ In Ruby : "my_separator first thing my_separator second thing".split(/(?=my_separator)/). Done!
      – Eric Duminil
      May 15 at 16:07

















    up vote
    6
    down vote













    As already commented, use the str.split() version itself:



    SEPARATOR = "my_separator "
    s = "my_separator first thing my_separator second thing"
    data = [SEPARATOR + part for part in s.split(SEPARATOR) if part]





    share|improve this answer





















    • You meant it like this! You won! :-D
      – VaNa
      May 15 at 15:19







    • 2




      Note that it doesn't work if 'my_separator' isn't present in the string.
      – Eric Duminil
      May 15 at 16:04

















    up vote
    1
    down vote













    your last line "repaired"



    import re
    s = "my_separator first thing my_separator second thing"
    data = re.split("(my_separator )", s)[1:]
    data = [data[i]+data[i+1] for i in range(0, len(data), 2)]





    share|improve this answer

















    • 1




      Although this one does not seem to be that elegant, it is correct and better than mine. Thanks!
      – VaNa
      May 15 at 15:18










    Your Answer




    StackExchange.ifUsing("editor", function ()
    return StackExchange.using("mathjaxEditing", function ()
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    );
    );
    , "mathjax-editing");

    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "196"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );








     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f194444%2fstring-cut-by-a-separator-with-the-separator-in-the-respective-list-element-in-p%23new-answer', 'question_page');

    );

    Post as a guest






























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    1
    down vote



    accepted










    hjpotters92’s answer is great for fixed separator strings. If the separators vary and one wants to join them with each subsequent match one can use the following two approaches, neither of which requires closures:



    1 Generator function



    def split_with_separator1(s, sep):
    tokens = iter(re.split(sep, s))
    next(tokens)
    while True:
    yield next(tokens) + next(tokens)


    The expression inside the loop works because the Python language guarantees left-to-right evaluation (unlike many other languages, e. g. C).



    2 Interleaved slices and binary map



    import operator

    def split_with_separator2(s, sep)
    tokens = re.split(sep, s)
    return map(operator.add, tokens[1::2], tokens[2::2])


    Of course one can slice with itertools.islice instead if one doesn't want to create two ephemeral token list copies.






    share|improve this answer

























      up vote
      1
      down vote



      accepted










      hjpotters92’s answer is great for fixed separator strings. If the separators vary and one wants to join them with each subsequent match one can use the following two approaches, neither of which requires closures:



      1 Generator function



      def split_with_separator1(s, sep):
      tokens = iter(re.split(sep, s))
      next(tokens)
      while True:
      yield next(tokens) + next(tokens)


      The expression inside the loop works because the Python language guarantees left-to-right evaluation (unlike many other languages, e. g. C).



      2 Interleaved slices and binary map



      import operator

      def split_with_separator2(s, sep)
      tokens = re.split(sep, s)
      return map(operator.add, tokens[1::2], tokens[2::2])


      Of course one can slice with itertools.islice instead if one doesn't want to create two ephemeral token list copies.






      share|improve this answer























        up vote
        1
        down vote



        accepted







        up vote
        1
        down vote



        accepted






        hjpotters92’s answer is great for fixed separator strings. If the separators vary and one wants to join them with each subsequent match one can use the following two approaches, neither of which requires closures:



        1 Generator function



        def split_with_separator1(s, sep):
        tokens = iter(re.split(sep, s))
        next(tokens)
        while True:
        yield next(tokens) + next(tokens)


        The expression inside the loop works because the Python language guarantees left-to-right evaluation (unlike many other languages, e. g. C).



        2 Interleaved slices and binary map



        import operator

        def split_with_separator2(s, sep)
        tokens = re.split(sep, s)
        return map(operator.add, tokens[1::2], tokens[2::2])


        Of course one can slice with itertools.islice instead if one doesn't want to create two ephemeral token list copies.






        share|improve this answer













        hjpotters92’s answer is great for fixed separator strings. If the separators vary and one wants to join them with each subsequent match one can use the following two approaches, neither of which requires closures:



        1 Generator function



        def split_with_separator1(s, sep):
        tokens = iter(re.split(sep, s))
        next(tokens)
        while True:
        yield next(tokens) + next(tokens)


        The expression inside the loop works because the Python language guarantees left-to-right evaluation (unlike many other languages, e. g. C).



        2 Interleaved slices and binary map



        import operator

        def split_with_separator2(s, sep)
        tokens = re.split(sep, s)
        return map(operator.add, tokens[1::2], tokens[2::2])


        Of course one can slice with itertools.islice instead if one doesn't want to create two ephemeral token list copies.







        share|improve this answer













        share|improve this answer



        share|improve this answer











        answered May 15 at 20:38









        David Foerster

        1,550316




        1,550316






















            up vote
            8
            down vote













            You can exploit zip and iterators to allow you to pair things together:



            data = [a + b for a, b in zip(*[iter(data)]*2)]



            You could use just re, and change the separator with a look ahead assertion.



            data = re.split(" (?=my_separator)", s)



            You can use str.split, and just add the separator back:



            sep = 'my_separator '
            data = s.split(sep)[1:]
            data = [sep + i for i in data]




            data = [sep + i for i in s.split(sep)]





            share|improve this answer























            • Didn't know about itertools recipes, thanks a lot! I consider the lookahead most elegant as I won't have to process it then.
              – VaNa
              May 15 at 14:31











            • The lookahead is not as general as I thought because split has to consume something and that something has to precede the separator :-( pairwise it is!
              – VaNa
              May 15 at 14:46











            • pairwise cuts it as (1,2),(2,3),(3,4),..., my code does (1,2),(3,4),....
              – VaNa
              May 15 at 15:15







            • 1




              @VaNa My bad, yes, I've fixed that
              – Peilonrayz
              May 15 at 15:19






            • 2




              @VaNa: The lookahead works fine, just not in Python. :-/ In Ruby : "my_separator first thing my_separator second thing".split(/(?=my_separator)/). Done!
              – Eric Duminil
              May 15 at 16:07














            up vote
            8
            down vote













            You can exploit zip and iterators to allow you to pair things together:



            data = [a + b for a, b in zip(*[iter(data)]*2)]



            You could use just re, and change the separator with a look ahead assertion.



            data = re.split(" (?=my_separator)", s)



            You can use str.split, and just add the separator back:



            sep = 'my_separator '
            data = s.split(sep)[1:]
            data = [sep + i for i in data]




            data = [sep + i for i in s.split(sep)]





            share|improve this answer























            • Didn't know about itertools recipes, thanks a lot! I consider the lookahead most elegant as I won't have to process it then.
              – VaNa
              May 15 at 14:31











            • The lookahead is not as general as I thought because split has to consume something and that something has to precede the separator :-( pairwise it is!
              – VaNa
              May 15 at 14:46











            • pairwise cuts it as (1,2),(2,3),(3,4),..., my code does (1,2),(3,4),....
              – VaNa
              May 15 at 15:15







            • 1




              @VaNa My bad, yes, I've fixed that
              – Peilonrayz
              May 15 at 15:19






            • 2




              @VaNa: The lookahead works fine, just not in Python. :-/ In Ruby : "my_separator first thing my_separator second thing".split(/(?=my_separator)/). Done!
              – Eric Duminil
              May 15 at 16:07












            up vote
            8
            down vote










            up vote
            8
            down vote









            You can exploit zip and iterators to allow you to pair things together:



            data = [a + b for a, b in zip(*[iter(data)]*2)]



            You could use just re, and change the separator with a look ahead assertion.



            data = re.split(" (?=my_separator)", s)



            You can use str.split, and just add the separator back:



            sep = 'my_separator '
            data = s.split(sep)[1:]
            data = [sep + i for i in data]




            data = [sep + i for i in s.split(sep)]





            share|improve this answer















            You can exploit zip and iterators to allow you to pair things together:



            data = [a + b for a, b in zip(*[iter(data)]*2)]



            You could use just re, and change the separator with a look ahead assertion.



            data = re.split(" (?=my_separator)", s)



            You can use str.split, and just add the separator back:



            sep = 'my_separator '
            data = s.split(sep)[1:]
            data = [sep + i for i in data]




            data = [sep + i for i in s.split(sep)]






            share|improve this answer















            share|improve this answer



            share|improve this answer








            edited May 15 at 15:15


























            answered May 15 at 11:28









            Peilonrayz

            24.3k336102




            24.3k336102











            • Didn't know about itertools recipes, thanks a lot! I consider the lookahead most elegant as I won't have to process it then.
              – VaNa
              May 15 at 14:31











            • The lookahead is not as general as I thought because split has to consume something and that something has to precede the separator :-( pairwise it is!
              – VaNa
              May 15 at 14:46











            • pairwise cuts it as (1,2),(2,3),(3,4),..., my code does (1,2),(3,4),....
              – VaNa
              May 15 at 15:15







            • 1




              @VaNa My bad, yes, I've fixed that
              – Peilonrayz
              May 15 at 15:19






            • 2




              @VaNa: The lookahead works fine, just not in Python. :-/ In Ruby : "my_separator first thing my_separator second thing".split(/(?=my_separator)/). Done!
              – Eric Duminil
              May 15 at 16:07
















            • Didn't know about itertools recipes, thanks a lot! I consider the lookahead most elegant as I won't have to process it then.
              – VaNa
              May 15 at 14:31











            • The lookahead is not as general as I thought because split has to consume something and that something has to precede the separator :-( pairwise it is!
              – VaNa
              May 15 at 14:46











            • pairwise cuts it as (1,2),(2,3),(3,4),..., my code does (1,2),(3,4),....
              – VaNa
              May 15 at 15:15







            • 1




              @VaNa My bad, yes, I've fixed that
              – Peilonrayz
              May 15 at 15:19






            • 2




              @VaNa: The lookahead works fine, just not in Python. :-/ In Ruby : "my_separator first thing my_separator second thing".split(/(?=my_separator)/). Done!
              – Eric Duminil
              May 15 at 16:07















            Didn't know about itertools recipes, thanks a lot! I consider the lookahead most elegant as I won't have to process it then.
            – VaNa
            May 15 at 14:31





            Didn't know about itertools recipes, thanks a lot! I consider the lookahead most elegant as I won't have to process it then.
            – VaNa
            May 15 at 14:31













            The lookahead is not as general as I thought because split has to consume something and that something has to precede the separator :-( pairwise it is!
            – VaNa
            May 15 at 14:46





            The lookahead is not as general as I thought because split has to consume something and that something has to precede the separator :-( pairwise it is!
            – VaNa
            May 15 at 14:46













            pairwise cuts it as (1,2),(2,3),(3,4),..., my code does (1,2),(3,4),....
            – VaNa
            May 15 at 15:15





            pairwise cuts it as (1,2),(2,3),(3,4),..., my code does (1,2),(3,4),....
            – VaNa
            May 15 at 15:15





            1




            1




            @VaNa My bad, yes, I've fixed that
            – Peilonrayz
            May 15 at 15:19




            @VaNa My bad, yes, I've fixed that
            – Peilonrayz
            May 15 at 15:19




            2




            2




            @VaNa: The lookahead works fine, just not in Python. :-/ In Ruby : "my_separator first thing my_separator second thing".split(/(?=my_separator)/). Done!
            – Eric Duminil
            May 15 at 16:07




            @VaNa: The lookahead works fine, just not in Python. :-/ In Ruby : "my_separator first thing my_separator second thing".split(/(?=my_separator)/). Done!
            – Eric Duminil
            May 15 at 16:07










            up vote
            6
            down vote













            As already commented, use the str.split() version itself:



            SEPARATOR = "my_separator "
            s = "my_separator first thing my_separator second thing"
            data = [SEPARATOR + part for part in s.split(SEPARATOR) if part]





            share|improve this answer





















            • You meant it like this! You won! :-D
              – VaNa
              May 15 at 15:19







            • 2




              Note that it doesn't work if 'my_separator' isn't present in the string.
              – Eric Duminil
              May 15 at 16:04














            up vote
            6
            down vote













            As already commented, use the str.split() version itself:



            SEPARATOR = "my_separator "
            s = "my_separator first thing my_separator second thing"
            data = [SEPARATOR + part for part in s.split(SEPARATOR) if part]





            share|improve this answer





















            • You meant it like this! You won! :-D
              – VaNa
              May 15 at 15:19







            • 2




              Note that it doesn't work if 'my_separator' isn't present in the string.
              – Eric Duminil
              May 15 at 16:04












            up vote
            6
            down vote










            up vote
            6
            down vote









            As already commented, use the str.split() version itself:



            SEPARATOR = "my_separator "
            s = "my_separator first thing my_separator second thing"
            data = [SEPARATOR + part for part in s.split(SEPARATOR) if part]





            share|improve this answer













            As already commented, use the str.split() version itself:



            SEPARATOR = "my_separator "
            s = "my_separator first thing my_separator second thing"
            data = [SEPARATOR + part for part in s.split(SEPARATOR) if part]






            share|improve this answer













            share|improve this answer



            share|improve this answer











            answered May 15 at 15:15









            hjpotter92

            4,89611538




            4,89611538











            • You meant it like this! You won! :-D
              – VaNa
              May 15 at 15:19







            • 2




              Note that it doesn't work if 'my_separator' isn't present in the string.
              – Eric Duminil
              May 15 at 16:04
















            • You meant it like this! You won! :-D
              – VaNa
              May 15 at 15:19







            • 2




              Note that it doesn't work if 'my_separator' isn't present in the string.
              – Eric Duminil
              May 15 at 16:04















            You meant it like this! You won! :-D
            – VaNa
            May 15 at 15:19





            You meant it like this! You won! :-D
            – VaNa
            May 15 at 15:19





            2




            2




            Note that it doesn't work if 'my_separator' isn't present in the string.
            – Eric Duminil
            May 15 at 16:04




            Note that it doesn't work if 'my_separator' isn't present in the string.
            – Eric Duminil
            May 15 at 16:04










            up vote
            1
            down vote













            your last line "repaired"



            import re
            s = "my_separator first thing my_separator second thing"
            data = re.split("(my_separator )", s)[1:]
            data = [data[i]+data[i+1] for i in range(0, len(data), 2)]





            share|improve this answer

















            • 1




              Although this one does not seem to be that elegant, it is correct and better than mine. Thanks!
              – VaNa
              May 15 at 15:18














            up vote
            1
            down vote













            your last line "repaired"



            import re
            s = "my_separator first thing my_separator second thing"
            data = re.split("(my_separator )", s)[1:]
            data = [data[i]+data[i+1] for i in range(0, len(data), 2)]





            share|improve this answer

















            • 1




              Although this one does not seem to be that elegant, it is correct and better than mine. Thanks!
              – VaNa
              May 15 at 15:18












            up vote
            1
            down vote










            up vote
            1
            down vote









            your last line "repaired"



            import re
            s = "my_separator first thing my_separator second thing"
            data = re.split("(my_separator )", s)[1:]
            data = [data[i]+data[i+1] for i in range(0, len(data), 2)]





            share|improve this answer













            your last line "repaired"



            import re
            s = "my_separator first thing my_separator second thing"
            data = re.split("(my_separator )", s)[1:]
            data = [data[i]+data[i+1] for i in range(0, len(data), 2)]






            share|improve this answer













            share|improve this answer



            share|improve this answer











            answered May 15 at 12:56









            bobrobbob

            2125




            2125







            • 1




              Although this one does not seem to be that elegant, it is correct and better than mine. Thanks!
              – VaNa
              May 15 at 15:18












            • 1




              Although this one does not seem to be that elegant, it is correct and better than mine. Thanks!
              – VaNa
              May 15 at 15:18







            1




            1




            Although this one does not seem to be that elegant, it is correct and better than mine. Thanks!
            – VaNa
            May 15 at 15:18




            Although this one does not seem to be that elegant, it is correct and better than mine. Thanks!
            – VaNa
            May 15 at 15:18












             

            draft saved


            draft discarded


























             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f194444%2fstring-cut-by-a-separator-with-the-separator-in-the-respective-list-element-in-p%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            Python Lists

            Aion

            JavaScript Array Iteration Methods