I want to alternate the first two characters into the rest of the string in python

1.1k views Asked by At

Ok so what im trying to do is to alternate the first two values in the string in the rest of the string.

what i have is..... "*+123"

what i want is ..... "1 * 2 + 3"

im sure the answer is simple but I've racked my head on this.....I am a beginner

ive tried separating the first two positions and putting them into separate variables and alternated that way:

THIS IS MY CODE

formula = '*+*123'    
first_part = formula[0:3]    
second_part = formula[3:len(formula_chosen)]    
print first_part    
print second_part    
expanded = ''

for i in range(len(second_part)-1):
    expanded = expanded + second_part[i] + first_part[i]
print expanded

but what i end up with is: "1*2+"

4

There are 4 answers

0
Jordan Reiter On BEST ANSWER

You are being very, very specific in what you are trying to do. If this is an exercise that you are trying to do, in which the instructions are, "Given a 5 character string, create a new string where the first two characters alternate with the last 3 in a new string" then the code above will work for you in this limited case.

If you are trying to solve a problem, however, it would be helpful to have more details about the problem you are trying to solve and why you want to solve it.

As en_Knight points out, this function does not work on a variety of inputs. And the point in computing, generally, is to create code that makes tasks easier by being general enough to solve the same problems many times with different inputs.

A few style notes: when getting sections of lists, you only need to provide the starting number when it is not 0, or the ending number when it is not through the end of the list. So instead of

second_part = formula[3:len(formula_chosen)]    

you can simply write:

second_part = formula[3:]    

where the empty part after : signals "Get all content to the end of the string".

To give you an idea of what I mean by writing code so it is a more general solution, here is a function that does what you describe on strings of any length: dividing them exactly in half and then alternating the characters.

def alternate_half(input):
    output = ""
    input_a = input[:len(input)/2]
    input_b = input[len(input)/2:]
    for pos, char in enumerate(input_b):
        output += char 
        if len(input_a) > pos:
            output += input_a[pos]
    return output

Explained:

  • def just sets up the function, named alternate_half, here with a parameter, or input value, called "input" that is the string you have labeled as formula above.
  • input[:len(input)/2]``input[len(input)/2:] - these are both just slices of the main list. It uses the trick above — that python automatically fills in 0 or the end of the list. It also uses the trick that when dividing by integers in Python, you get an integer in return. So for example in the case of a 5 length string, len(input)/2 is 2, so input_a is the first 2 characters, and input_b is the characters 2 through the end of the string, so "123".
  • enumerate returns a counter for each item in an iterable (such as a string). So enumerate("*+123") is functionally equivalent to [(0, '*'), (1, '+'), (2, '1'), (3, '2'), (4, '3')]. So we can use the positional argument in input_a and append to the corresponding character in input_b.
  • Finally we just check to make sure that if input_a is shorter, we don't try to get a character past the length of the string. Because we're dividing the strings in half, input_a will never be more than one character shorter than input_b.
0
en_Knight On

You're close!

Here's a version of your code that works - keep going by one character, then chop off the ending

formula = '*+*123'    
first_part = formula[0:3]    
second_part = formula[3:len(formula)]    
print first_part    
print second_part    
expanded = ''

for i in range(len(second_part)):#changed here
    expanded = expanded + second_part[i] + first_part[i]

expanded = expanded[:-1] #changed here
print expanded

You probably don't like that extra chop (you shouldn't). The problem with your algorithm is that it doesn't handle well when things aren't even in length, becuase you're dividing the list in half. A better way to handle even/oddness is with the "modulo" operator

Modulo operator in Python

Here's a fun way to solve the problem using some Python tricks, if you want to make your way through it it might be educational :)

formula = '*+123'   
out = ''

for c1,c2 in zip(formula,formula[::-1]):
    out += c2 + c1
out = out[:len(out)/2][::-1]     

print(out)
1
br3w5 On

Try using itertools which is worth checking out when working with iterables in Python.

import itertools

def alternate_characters(formula):
    try:
        if type(formula) is str:
            operators = formula[:2]
            operands = formula[2:]
            iterable = itertools.izip_longest(operands, operators)
            alt = ''
            for tup in iterable:
                for k in tup:
                    if k is not None:
                        alt += k

            return alt
    except TypeError:
        print "Formula must be a string"

With an input string:

print alternate_characters('*+123')
'1*2+3'

With a non-string input:

print alternate_characters(*+123)
'TypeError: alternate_characters() argument after * must be a sequence, not int'
0
thekindlyone On

something like this, using itertools.cycle(). This will work for any length string and any length of part1 that you can decide..(just replace that 2 with a variable)

In [35]: from itertools import cycle

In [36]: s='*+123'

In [37]: part1=cycle(s[:2])

In [38]: part2=s[2:]

In [39]: processed_string=''.join([digit+part1.next() for digit in part2])[:-1]

In [40]: processed_string
Out[40]: '1*2+3'

Take apart first part, make a cycle from it. cycle keeps cycling iterable on next().
A list comprehension constructs a list of each digit in part2 concatenated with the next() on the itertools.cycle called part1(This makes it alternate between * and +).
''.join() this list to make a string. Get rid of the trailing extra as it is not needed for the last iteration.

Explanation

In [50]: part1=cycle(s[:2])

In [51]: part1.next()
Out[51]: '*'

In [52]: part1.next()
Out[52]: '+'

In [53]: part1.next()
Out[53]: '*'

In [54]: part1.next()
Out[54]: '+'

In [55]: #alternates

In [56]: # list comp

In [57]: [digit for digit in part2]
Out[57]: ['1', '2', '3']

In [58]: [digit+part1.next() for digit in part2]
Out[58]: ['1*', '2+', '3*']

In [59]: # this is a list of strings and can be joined using join.

In [60]: ''.join([digit+part1.next() for digit in part2])
Out[60]: '1+2*3+'

In [61]: # this has a trailing extra character. get rid of it using slices

In [62]: ''.join([digit+part1.next() for digit in part2])[:-1]
Out[62]: '1*2+3'

In [63]: #solution

To avoid the dropping of last character at the end, you can construct the list for all chars of part2 except the last(part2[:-1]) and then add the last character of part2(part2[-1]) like this:

In [64]: part1=cycle(s[:2])

In [65]: ''.join([digit+part1.next() for digit in part2[:-1]])
Out[65]: '1*2+'

In [66]: ''.join([digit+part1.next() for digit in part2[:-1]])+part2[-1]
Out[66]: '1*2+3'

You can enclose it in a function like this:

In [67]: # enclose in a function

In [68]: def process_text(text,no_of_symbols):
   ....:     part1=cycle(text[:no_of_symbols])
   ....:     part2=text[no_of_symbols:]
   ....:     return ''.join([digit+part1.next() for digit in part2])[:-1]
   ....: 

In [69]: process_text('+*-123456',3)
Out[69]: '1+2*3-4+5*6'