0

I want to divide text into pairs.

  • Input: text = "abcde"

  • Goal Output: result = ["ab", "cd", "e_"]

  • Current Output: result = ['ab', 'abcd']

My current code looks like this. But I do not know how I do that now. Anyone has a tip for me?

def split_pairs(text):
    result = []
    if text is None or not text:
        return []
    pair = ""
    for i in range(len(text)):
        if i % 2 == 0:
            pair += text[i]
            pair += text[i+1]
        else:
            result.append(pair)
    return result
J'e
  • 3,014
  • 4
  • 31
  • 55
D2F2
  • 21
  • 3
  • 1
    Try using `range(0, len(text), 2)` and remove the `if`/`else` conditioning. The third argument in `range` is the step length. – Timus Sep 30 '20 at 11:38

5 Answers5

3

You could use a list comprehension to zip together the even values with the corresponding odd values. And using itertools.zip_longest you can use the fillvalue argument to provide a "fill in" if there is a length mismatch.

>>> from itertools import zip_longest
>>> s = 'abcde'
>>> pairs = [i+j for i,j in zip_longest(s[::2], s[1::2], fillvalue='_')]
>>> pairs
['ab', 'cd', 'e_']
Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
2

You should reset your "pair" variable once appended to "result"

def split_pairs(text):
result = []
if text is None or not text:
    return []
pair = ""
for i in range(len(text)):
    if i % 2 == 0:
        pair += text[i]
        pair += text[i+1]
    else:
        result.append(pair)
        pair = ""
return result
2

You could also use a list comprehension over a range with 3rd step parameter and add ljust to add _. This will also work nicely for more than just pairs:

>>> s = "abcde"
>>> k = 2
>>> [s[i:i+k].ljust(k, "_") for i in range(0, len(s), k)]
['ab', 'cd', 'e_']
tobias_k
  • 81,265
  • 12
  • 120
  • 179
1

I am not if your code needed to be in the format you originally wrote it in, but I wrote the below code that gets the job done.

def split_pairs(text):
    if len(text) % 2 == 0:
        result = [text[i:i+2] for i in range(0, len(text), 2)]
    else:
        result = [text[i:i+2] for i in range(0, len(text), 2)]
        result[-1]+="_"
    return result
1

The issue here is that the "pair" variable is never reinitialized to "". Make sure you make it an empty string in your else block.

def split_pairs(text):
    result = []
    if text is None or not text:
        return []
    pair = ""
    for i in range(len(text)):
        if i % 2 == 0:
            pair += text[i]
            pair += text[i+1]
        else:
            result.append(pair)
            pair = ""  # Make sure you reset it
    return result

If you want to have a "_" at the end (in case of an odd number of character), you could do like the following:

def split_pairs(text):
    result = []
    if text is None or not text:
        return []
    pair = "__"  # Setting pair to "__" by default
    for i in range(len(text)):
        if i % 2 == 0:
            pair[0] = text[i]
            if i < len(text):  # Avoiding overflow
                pair[1] = text[i+1]
        else:
            result.append(pair)
            pair = "__"  # Make sure you reset it
    if pair != "__":  # Last bit 
        result.append(pair)
    return result
mrico
  • 11
  • 1