1

Say I have a list like this:

a = [[1, 2, 3], [4, 5, 6]]
filler = ['cat']

How could I get

b = [[1 ,2 ,3], ['cat'], [4, 5, 6], ['cat']] 

As an output?

  • Related, but I guess not _quite_ a duplicate: [Add an item between each item already in the list](http://stackoverflow.com/q/5920643/577088). – senderle Nov 04 '12 at 16:29

9 Answers9

3

I prefer to use itertools for stuff like this:

>>> import itertools as it
>>> a = [[1, 2, 3], [4, 5, 6]]
>>> filler = ['cat']
>>> list(it.chain.from_iterable(it.izip(a, it.repeat(filler))))
[[1, 2, 3], ['cat'], [4, 5, 6], ['cat']]
stranac
  • 26,638
  • 5
  • 25
  • 30
3

I like the itertools-based solutions posted here, but here's an approach that doesn't require list comprehensions or itertools, and I bet it's super fast.

new_list = [filler] * (len(a) * 2)
new_list[0::2] = a
senderle
  • 145,869
  • 36
  • 209
  • 233
2

Not pythonic but seems to work.

list = [[1, 2, 3], [4, 5, 6]]
result = []
for e in list:
    result.append(e)
    result.append(['cat'])
result.pop()

Found at this post: Add an item between each item already in the list

Community
  • 1
  • 1
cwoebker
  • 3,158
  • 5
  • 27
  • 43
  • I saw that post, but all those examples return error messages for me. –  Nov 04 '12 at 15:40
2

Here's an idea:

import itertools

a = [[1, 2, 3], [4, 5, 6]]
filler = ['cat']
print list(itertools.chain.from_iterable(zip(a, [filler] * len(a))))

Output:

[[1, 2, 3], ['cat'], [4, 5, 6], ['cat']]
arshajii
  • 127,459
  • 24
  • 238
  • 287
1

something like this using itertools.islice() and itertools.cycle():

cycle() is used to repeat an item, and used islice() cut the number of repeatation to len(a), and then use izip() or simple zip() over a and the iterator returned by islice() , this will return list of tuples.

you can then flatten this using itertools.chain().

In [72]: a
Out[72]: [[1, 2, 3], [4, 5, 6]]

In [73]: b
Out[73]: ['cat']

In [74]: cyc=islice(cycle(b),len(a))

In [75]: lis=[]

In [76]: for x in a:
    lis.append(x)
    lis.append([next(cyc)])
   ....:     

In [77]: lis
Out[77]: [[1, 2, 3], ['cat'], [4, 5, 6], ['cat']]

or:

In [108]: a
Out[108]: [[1, 2, 3], [4, 5, 6]]

In [109]: b
Out[109]: ['cat']

In [110]: cyc=islice(cycle(b),len(a))

In [111]: list(chain(*[(x,[y]) for x,y in izip(a,cyc)]))
Out[111]: [[1, 2, 3], ['cat'], [4, 5, 6], ['cat']]
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
  • Why not just use flatten for the joining? – Marcin Nov 04 '12 at 15:53
  • It's incorrect in that (a) it's not especially well written; and (b) it completely fails to capture the benefits of either iterators or explicit iteration by bastardising the two. – Marcin Nov 04 '12 at 15:56
  • @Marcin added a `chain()` based anwser that used flattening. – Ashwini Chaudhary Nov 04 '12 at 16:05
  • I still don't think is especially useful, because of the way it is written, and the lack of explication, but I have withdrawn my downvote. – Marcin Nov 04 '12 at 16:06
  • 1
    @AshwiniChaudhary your answer was never incorrect, don't let yourself get sucked into an argument, just ignore the troll among us. +1 to this answer. – Óscar López Nov 04 '12 at 16:26
  • 1
    @ÓscarLópez I just saw your answer and a +1 to your answer as well which didn't deserved a -1, I think it's unreasonable to -1 an answer just on the basis of complexity. – Ashwini Chaudhary Nov 04 '12 at 16:46
0
a = [[1, 2, 3], [4, 5, 6]]
filler = ['cat']
out = []

for i in a:
    out.append(i)
    out.append(filler)
toxotes
  • 1,386
  • 14
  • 20
0
result = [si for i in zip(a, [filler]*len(a)) for si in i]
  • -1 cryptic list comprehension used for flattening without explication. There's a perfectly good library function to achieve the same effect. – Marcin Nov 04 '12 at 15:45
  • 1
    +1, because I don't think it should _always_ be necessary to import a module for a simple, one-off transformation like this. _But_ -- I would break it into two separate lines. `pairs = zip(a, [filler] * len(a)); chained_pairs = [item for pair in pairs for item in pair]`. It's more self-documenting that way. – senderle Nov 04 '12 at 16:02
0

Try this, as a one-liner:

from operator import add
a = [[1, 2, 3], [4, 5, 6]]
filler = ['cat']

reduce(add, ([x, filler] for x in a))
> [[1, 2, 3], ['cat'], [4, 5, 6], ['cat']]

Or even simpler, without using reduce:

sum(([x, filler] for x in a), [])
> [[1, 2, 3], ['cat'], [4, 5, 6], ['cat']]

Both solutions do the same: first, create a generator of [element, filler] and then flatten the resulting stream of pairs. For efficiency, the first step is performed using generators to avoid unnecessary intermediate lists.

UPDATE:

This post is a textbook example of why a troll must not be fed in an online forum. See the comments to see what I mean. It's better to just ignore the troll.

Óscar López
  • 232,561
  • 37
  • 312
  • 386
-1
    python 3.2

    a = [[1, 2, 3], [4, 5, 6]]
    b = ['cat']
    _=[a.insert(x,b) for x in range(1,len(a)*2,2)]
raton
  • 418
  • 5
  • 14