The Only One Around
The Only One Around

Reputation: 181

add an element N times between elements in list

I have this code that intersperses from python: most elegant way to intersperse a list with an element.

def joinit(iterable, delimiter):
    it = iter(iterable)
    yield next(it)
    for x in it:
        yield delimiter
        yield x

I would like to do about the same thing, only that I can add an element n times between the elements in the list.

Example:

joinNTimes(3,"a",[1,2,3])

Will become

[1,"a","a","a",2,"a""a","a",3,"a","a","a"]

Thanks.

Upvotes: 0

Views: 110

Answers (6)

Tomalak
Tomalak

Reputation: 338396

def joinit(iterable, delimiter):
    for x in iterable:
        yield x
        if isinstance(delimiter, list):
            for y in list(delimiter):
                yield y
        else:
            yield delimiter

and

list(joinit([1, 2, 3], ['a', 'a']))

returns

[1, 'a', 'a', 2, 'a', 'a', 3, 'a', 'a']

Advantage: the semantics of joinit stay the same for single-element delimiters and for multi-element delimiters. The function caller decides, not the function.

Hint: ['a', 'a'] is ['a'] * 2 or list('a' * 2)

Upvotes: 0

nix
nix

Reputation: 111

You problem is simpler because you only need to insert delimiter after every iterable element.

def joinNTimes(count, delimiter, iterable):
    for x in iterable:
        yield x
        for i in xrange(count):
            yield delimiter

Upvotes: 1

ronakg
ronakg

Reputation: 4212

You just need another for loop inside -

def joinNtimes(delimiter, times, iterable):
    it = iter(iterable)
    yield next(it)
    for x in it:
        for i in range(times):
            yield delimiter
        yield x

A cleaner version of the same function is posted by @Nix. You don't need to convert iterable.

Upvotes: 0

user2489252
user2489252

Reputation:

I am wondering, what's the point of iter(iterable) here, does it have any advantages to use it? Can't it simply be:

def joinit(count, iterable, delimiter):
    for x in iterable:
        yield x
        for _ in range(count):
            yield delimiter

list(joinit(2, [1,2,3], 'a'))

Out:

[1, 'a', 'a', 2, 'a', 'a', 3, 'a', 'a']

Upvotes: 1

Chris Billington
Chris Billington

Reputation: 895

Adding a parameter n to the joinit() function and an extra loop within it does the job:

def joinit_n(iterable, delimiter, n):
    it = iter(iterable)
    yield next(it)
    for x in it:
        # yield the delimiter n times instead of just once:
        for i in range(n):
            yield delimiter
        yield x

If you definitely want the delimiter to be added on the end n times too, as in your example, then you'll want to simply add another loop to the end:

def joinit_n(iterable, delimiter, n):
    it = iter(iterable)
    yield next(it)
    for x in it:
        # yield the delimiter n times instead of just once:
        for i in range(n):
            yield delimiter
        yield x
    # And another n delimiters at the end
    for i in range(n):
        yield delimiter

There are surely ways to cleverly one-liner this, but readability counts! Explicitly writing out the loop is just fine.

Upvotes: 0

lazappi
lazappi

Reputation: 196

Here's my solution. I just added an extra loop to yield the delimiter multiple times. It doesn't return the last set of the delimiter, but the code for the single version you posted doesn't seem to either.

def joinNTimes(n, delimiter, iterable):
    it = iter(iterable)
    yield next(it)
    for x in it:
        for i in xrange(n):
            yield delimiter
        yield x

Upvotes: 1

Related Questions