georg
georg

Reputation: 215029

Return at least X results from split

split has a maxsplit parameter, which is useful when you want at most X results. If there something similar to return at least X results and populate the rest with Nones. I'd like to be able to write

 a, b, c = 'foo,bar'.magic_split(',', 3)

and have a=foo, b=bar and c=None.

Any ideas how to write such a function?

Upd. I ended up with a solution which is a combination of this and this answers:

>>> def just(n, iterable, fill=None):
...     return (list(iterable) + [fill] * n)[:n]
... 
>>> just(3, 'foo,bar'.split(','))
['foo', 'bar', None]

Upvotes: 2

Views: 225

Answers (4)

Sven Marnach
Sven Marnach

Reputation: 602345

There is no such parameter to str.split(). A hack to achieve this would be

a, b, c = ('foo,bar'.split(',', 2) + [None] * 3)[:3]

Not sure if I recommend this code, though.

Upvotes: 1

alexis
alexis

Reputation: 50220

Since you ask for a string method, you can start by deriving from str:

>>> class magicstr(str):
    def magic_split(self, sep=None, mlen=0):
        parts = self.split(sep)
        return parts + [None]* (mlen - len(parts))


>>> test = magicstr("hello there, ok?")
>>> test.magic_split(",", 3)
['hello there', ' ok?', None]

Upvotes: 1

Kabie
Kabie

Reputation: 10663

I would use a more general function for that:

def fill(iterable, n):
    tmp = tuple(iterable)
    return tmp + (None,)*(n - len(tmp))

Then:

a, b, c = fill('foo,bar'.split(','), 3)

Upvotes: 1

soulcheck
soulcheck

Reputation: 36777

One way would be:

from itertools import chain
from itertools import repeat
from itertools import islice 

def magic_split(seq, sep, n, def_value=None):
    return list(islice(chain(seq.split(sep), repeat(def_value)), n))

You could just return the return value of islice if you don't need the list.

If you don't want the values to be cut off when n is less than number of split elements in seq, the modification is trivial:

def magic_split(seq, sep, n, def_value=None):
    elems = seq.split(sep)
    if len(elems) >= n:
         return elems

    return list(islice(chain(elems, repeat(def_value)), n))

Upvotes: 5

Related Questions