简体   繁体   中英

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.

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

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

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']

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 .

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.

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM