Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python3 string "abcd" print: aababcabcd?

Tags:

python

string

If a have a string like abcd or 1234 etc. how can I print together, the first character, then the first two characters, then the first three etc. all together?

For example for a string = 1234 I would like to print/return 1121231234 or aababcabcd

I have this code so far:

def string_splosion(str):
    i = 0
    while i <= len(str):
        i += 1
        print(str[:i])
print(string_splosion('abcd'))

But it prints/returns it in separate lines. I could write it manually as print(str[0:1], str[1:2] <...>) but how do I make python do it as I don't know how long the string is going to be?

like image 891
AL12 Avatar asked Dec 26 '22 00:12

AL12


1 Answers

You shouldn't use str as a variable name, because it shadows the built-in str type. You could join the sliced strings together in your loop:

def string_splosion(string):
    i, result = 0, ''
    while i < len(string): # < instead of <=
        i += 1
        result += string[:i]
    return result

It's possible to shorten your code a little using str.join and range:

def string_splosion(string):
    return ''.join(string[:i] for i in range(1, len(string) + 1))

or using itertools.accumulate (Python 3.2+):

import itertools
def string_splosion(string):
    return ''.join(itertools.accumulate(string))

itertools.accumulate approach appears to be 2 times faster than str.join one and about 1.5 times faster than the original loop-based solution:

string_splosion_loop(abcdef): 2.3944241080715223
string_splosion_join_gen(abcdef): 2.757582983268288
string_splosion_join_lc(abcdef): 2.2879220573578865
string_splosion_itertools(abcdef): 1.1873638161591886

The code I used to time the functions is

import itertools
from timeit import timeit

string = 'abcdef'

def string_splosion_loop():
    i, result = 0, ''
    while i < len(string):
        i += 1
        result += string[:i]
    return result

def string_splosion_join_gen():
    return ''.join(string[:i] for i in range(1, len(string) + 1))

def string_splosion_join_lc():
    # str.join performs faster when the argument is a list
    return ''.join([string[:i] for i in range(1, len(string) + 1)])

def string_splosion_itertools():
    return ''.join(itertools.accumulate(string))

funcs = (string_splosion_loop, string_splosion_join_gen, 
         string_splosion_join_lc, string_splosion_itertools)

for f in funcs:
    print('{.__name__}({}): {}'.format(f, string, timeit(f)))
like image 90
vaultah Avatar answered Jan 04 '23 12:01

vaultah