Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I have this implementation of the split algorithm that different from .split() method you can use with multiple delimiters. Is this a good way of implementing it (more performance)?

def split(str, delim=" "):
    index = 0
    string = ""
    array = []
    while index < len(str):
        if str[index] not in delim: 
            string += str[index]
        else:
            if string: 
                array.append(string)
                string = ""
        index += 1
    if string: array.append(string)
    return array

Using the standard .split() method:

>>> print "hello = 20".split()
['hello', '=', '20']

>>> print "one;two; abc; b ".split(";")
['one', 'two', ' abc', ' b ']

Using my implementation:

>>> print split("hello = 20")
['hello', '=', '20']

>>> print split("one;two; abc; b ", ";")
['one', 'two', ' abc', ' b ']

Multiple delimiters:

>>> print split("one;two; abc; b.e. b eeeeee.e.e;;e ;.", " .;")
['one', 'two', 'abc', 'b', 'e', 'b', 'eeeeee', 'e', 'e', 'e']

>>> print split("foo barfoo;bar;foo bar.foo", " .;")
['foo', 'barfoo', 'bar', 'foo', 'bar', 'foo']

>>> print split("foo*bar*foo.foo bar;", "*.")
['foo', 'bar', 'foo', 'foo bar;']

Obs: We can do something like using re.split().

share|improve this question
2  
Post rolled back. Please don't edit the original code based on answers; that will invalidate them. If you'd like further review of your newer code, ask a new follow-up question. –  Jamal Apr 19 at 5:56

2 Answers 2

up vote 3 down vote accepted

There's no need to iterate using that while, a for is good enough.

Also string concatenation (+=) is expensive. It's better to use a list and join the elements at the end.

def split(s, delim=" "):
    words = []
    word = []
    for c in s:
        if c not in delim:
            word.append(c)
        else:
            if word:
                words.append(''.join(word))
                word = []
    if word:
        words.append(''.join(word))
    return words

There's also a one-liner solution based on itertools.groupby:

import itertools

def isplit(s, delim=" "):
    return (''.join(word)
            for is_word, word in itertools.groupby(s, lambda c: c not in delim)
            if is_word)

def split(s, *args, **kwargs):
    return list(isplit(s,  *args, **kwargs)) # or use list comprehension
share|improve this answer
1  
It does not work properly. ['one', 'two', ' abc', ' b', 'e', [' ', 'b', ' ', 'b', ' ', 'b', ' ']] –  dxhj Apr 19 at 3:28
    
It'd should return: ['one', 'two', ' abc', ' b', 'e', ' b b b '] –  dxhj Apr 19 at 3:29
    
For what input? –  Cristian Ciupitu Apr 19 at 3:29
    
For this: "one;two; abc; b.e. b b b " with these delimiters ";.". –  dxhj Apr 19 at 3:29
    
You're right, I forgot to join the characters for the last word. –  Cristian Ciupitu Apr 19 at 3:33

I would suggest caution if your concerned about the performance vs the built in split. I am fairly sure you would be replacing c code with python code.

A couple of notes about your implementation:

  • You use the variable name str which is also a built in type, you should avoid if possible.
  • Each time you loop around you add a character which really builds another string, perhaps you could keep going until you find a delimiter and just add all those at 1 time.
  • Also might be worth thinking about wrapping the built in.. (ie calling multiple times)
share|improve this answer
    
I'd like to add that choosing string for a variable name might hide the string module. –  Cristian Ciupitu Apr 19 at 9:39

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.