Inserting an item after each item in a list (Python) - python

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?

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

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

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

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

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

a = [[1, 2, 3], [4, 5, 6]]
filler = ['cat']
out = []
for i in a:
out.append(i)
out.append(filler)

result = [si for i in zip(a, [filler]*len(a)) for si in i]

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.

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

Related

Mapping a list right in Python

I have a question on how to map correctly my list.
I have the following code:
class Bar():
def __init__(self, i, j):
self.i = i-1
self.j = j-1
For the following list:
bars = [Bar(1,2), Bar(2,3), Bar(3,4), Bar(4,5), Bar(5,1),Bar(1,4), Bar(2,4), Bar(4,6), Bar(6,5)]
But for my problem, I have an array like this:
elementsmat=[[1, 1, 2], [2, 2, 3], [3, 3, 4], [4, 4, 5], [5, 5, 1], [6, 1, 4], [7, 2, 4], [8, 4, 6], [9, 6, 5]]
I used the following code to obtain an array where I removed the first element of each list of the list and then transformed it into a list.
s= np.delete(elementsmat, 0, 1)
r = s.tolist()
Output: [[1, 2], [2, 3], [3, 4], [4, 5], [5, 1], [1, 4], [2, 4], [4, 6], [6, 5]]
So, how can I apply the Bar function to all the elements of my new array correctly? I did this but I got the following error.
bars = map(Bar,r)
__init__() missing 1 required positional argument: 'j'
I thought it could be because in the first one the list has () and in my list I have [], but I am not sure.
You can use itertools.starmap instead of map (after importing itertools). Your current way calls Bar([1, 2]). starmap unpacks the lists into arguments. A generator/list comprehension is also an option.
(Bar(*x) for x in r)
Now you see why it's called starmap.
You need to unpack the nested lists into the call to Bar():
l = list(map(lambda x: Bar(*x), r))
itertools.starmap does the same thing.
Or, you can use a list-comprehension:
l = [Bar(i, j) for i, j in r]
A built-in functional approach
lst = [[1, 2], [2, 3], [3, 4], [4, 5], [5, 1], [1, 4], [2, 4], [4, 6], [6, 5]]
map(Bar, *zip(*lst))

Join list of lists into a delimiter separated list of lists

I have the following list of lists and a delimiter:
lsts = [[1, 2, 3], [4, 5], [6]]
delim = ['delim']
I'd like to mimic the string.join() behavior.
expected output is:
lst = [[1, 2, 3], ['delim'], [4, 5], ['delim'], [6]]
I tried:
from itertools import chain
n = 2
ele = 'x'
lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
list(chain(*[lst[i:i+n] + [ele] if len(lst[i:i+n]) == n else lst[i:i+n] for i in xrange(0, len(lst), n)]))
# which flattens the list and then inserst elements every second position,
# which doesn't help if the lists inside the list are of different length.
Try this:
lsts = [[1, 2, 3], [4, 5], [6]]
delim = ['delim']
place_holder = []
for i in lsts:
place_holder.append(i)
place_holder.append(delim)
place_holder.pop() # Pop the last element :)
print(place_holder)
You can use slice assignment
def list_join(seq, delim):
res = [delim]*(len(seq) * 2 - 1)
res[::2] = seq
return res
delim = ['delim']
# empty list
lsts = [[]]
print(list_join(lsts, delim))
# even length
lsts = [[1, 2, 3], [4, 5], [6], [7]]
print(list_join(lsts, delim))
# odd length
lsts = [[1, 2, 3], [4, 5], [6]]
print(list_join(lsts, delim))
Output
[[]]
[[1, 2, 3], ['delim'], [4, 5], ['delim'], [6], ['delim'], [7]]
[[1, 2, 3], ['delim'], [4, 5], ['delim'], [6]]
Here is my solution. It looks like the shortest code.
for i in range(len(lsts) - 1, 0, -1):
lsts.insert(i, delim)
print(lsts)
This uses a simple for loop that validates the position on the item isn’t the last item before adding the delimiter.
lsts = [[1, 2, 3], [4, 5], [6]]
delim = ['delim']
output = []
for i, l in enumerate(lsts):
output.append(l)
if i < (len(lsts) - 1):
output.append(delim)
After trying to solve it for quite a while and reviewing the other answers, I came up with an other alternative as well.
lsts = [[1, 2, 3], [4, 5], [6]]
delim = ['delim']
[x for t in zip(lsts,[delim]*len(lsts)) for x in t][:-1]
# Out[44]: [[1, 2, 3], ['delim'], [4, 5], ['delim'], [6]]

Split the first and second part of list of list into two sublists

I am facing an issue given below and I want to separate the 0th element and the 1st element in two separate lists. for eg I have a list
a = [[1, 2], [3,4], [5,6], [7,8]]
I want two lists like:
a0 = [1,3,5,7]
a2 = [2,4,6,8]
Can anyone help me with this please?
You can use zip
a = [[1, 2], [3, 4], [5, 6], [7, 8]]
a = [[*x] for x in zip(*a)]
print(a[0], a[1]) # [1, 3, 5, 7] [2, 4, 6, 8]
You can do this -
a = [[1, 2],[3,4],[5,6],[7,8]]
a0 = []
a2 = []
for i in a:
a0.append(i[0])
a2.append(i[1])
print(a0)
print(a2)
Using a list comprehension:
a = [[1, 2],[3,4],[5,6],[7,8]]
a0 = [x[0] for x in a]
a2 = [x[1] for x in a]
print(a0) # [1, 3, 5, 7]
print(a2) # [2, 4, 6, 8]
a = [[1, 2],[3,4],[5,6],[7,8]]
a0 = []
a1 = []
for x in a:
a0.append(x[0])
a1.append(x[1])
use chain to flatten the list, then calculate the middle index, then split it into two lists from the middle index
In [1]: from itertools import chain
In [2]: a = [[1, 2],[3,4],[5,6],[7,8]]
In [3]: flat = list(chain.from_iterable(a))
In [4]: flat
Out[4]: [1, 2, 3, 4, 5, 6, 7, 8]
In [5]: middle = len(flat) // 2
In [6]: first_half = flat[:middle]
In [7]: second_half = flat[middle:]
In [10]: first_half
Out[10]: [1, 2, 3, 4]
In [11]: second_half
Out[11]: [5, 6, 7, 8]
You can try below code
import numpy as np
a = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
np.array(a).T.tolist()
gives as
[[1, 3, 5, 7, 9], [2, 4, 6, 8, 10]]

Is there a way to combine a list like this?

assume that a and b are list.
a = [[1], [2]]
b = [[5, 6, 7], [3, 4, 5]]
I want to get a list which is
[[1,5,6,7], [2,3,4,5]]
Is there any way to do that effectively? Either lists or numpy array is OK.
zip is your friend:
>>> a = [[1], [2]]
>>> b = [[5, 6, 7], [3, 4, 5]]
>>> [x+y for x, y in zip(a, b)]
[[1, 5, 6, 7], [2, 3, 4, 5]]
You can also use map; the operator module provides a ready-made definition of lambda x,y: x + y for such uses.
>>> import operator
>>> list(map(operator.add, a, b))

sort a matrix using its value in python

For example I have a matrix
a = [[6,8,9],[7,4,3],[1,2,5]]
now I want to sort matrix like as below
a = [[1,2,3],[4,5,6],[7,8,9]]
please help me I am new to python.
For list-of-list, you can clone the shape like this
>>> from itertools import chain
>>> a = [[6,8,9],[7,4,3],[1,2,5]]
>>> it = iter(sorted(chain.from_iterable(a)))
>>> [[next(it) for j in i] for i in a]
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Use chain.from_iterable
>>> a = [[6,8,9],[7,4,3],[1,2,5]]
>>> from itertools import chain
>>> l = sorted(chain.from_iterable(a))
>>> [l[i:i+3] for i in range(0, len(l),3)]
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

Categories