sort a matrix using its value in python - 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]]

Related

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

Python merging list of lists with varying length

I want to write a function that merges a list of lists. The lists can be of varying lengths.
selected_cells = [[[1],[2],[3]], [[4],[5],[6]], [[7],[8]]]
My expected output would be [[1,4,7], [2,5,8], [3,6]]
I've written the following function
def merge(lst1, lst2):
print('Merging', lst1, 'and', lst2)
return [(sub + [lst2[i][-1]]) for i, sub in enumerate(lst1) if i < len(lst2)]
for idx, cell in enumerate(selected_cells):
if idx < (len(selected_cells)-1):
print(idx)
selected_cells[0] = merge(selected_cells[0], selected_cells[idx+1])
print('Output', selected_cells[0])
However this outputs [[1, 4, 7], [2, 5, 8]]
I feel like I'm missing something simple here and it's driving me nuts. Any help would be appreciated
As written in comments, you can use zip_longest from itertools module.
>>> selected_cells = [[[1],[2],[3]], [[4],[5],[6]], [[7],[8]]]
>>> from itertools import zip_longest
>>> L = list(zip_longest(*selected_cells))
>>> L
[([1], [4], [7]), ([2], [5], [8]), ([3], [6], None)]
And then flatten the tuples and remove the None values:
>>> [[x[0] for x in t if x] for t in L]
[[1, 4, 7], [2, 5, 8], [3, 6]]
Another option is to use a fold (functools.reduce):
>>> selected_cells = [[[1],[2],[3]], [[4],[5],[6]], [[7],[8]]]
>>> import functools
>>> functools.reduce(lambda acc, x: [acc[i] + (x[i] if i < len(x) else []) for i in range(len(acc))], selected_cells)
[[1, 4, 7], [2, 5, 8], [3, 6]]
That's perhaps less intuitive, though.
You can use zip_longest as stated in the comments, because zip will stop at the shortest iterable, for example:
from itertools import zip_longest
selected_cells = [[[1],[2],[3]], [[4],[5],[6]], [[7],[8]]]
output = [
[cell[0] for cell in row if cell is not None]
for row in zip_longest(*selected_cells)
]
print(output)
>>> [[1, 4, 7], [2, 5, 8], [3, 6]]

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

Inserting an item after each item in a list (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)]

better way to convert list element into a list like this one

i think this should be very easy , but i really don't know how to write it in a better way, if you know please tell me
#there are some points in text files and was read into a list
s = ['3,4','4,5','6,5','7,8']
#break s element to (x,y) form every element should convert to number type
points = []
for pStr in s:
ss = pStr.split(',')
points.append([int(p) for p in ss])
print(points) #[[3, 4], [4, 5], [6, 5], [7, 8]]
better write it in one line please
using a list comprehension:
In [19]: s = ['3,4','4,5','6,5','7,8']
In [21]: [[int(y) for y in x.split(',')] for x in s]
Out[21]: [[3, 4], [4, 5], [6, 5], [7, 8]]
If using Python 2.x you can do the following:
points = [map(int, x.split(',')) for x in s]
If using Python 3.x you'll need to pass the result of map() to list(), as it returns an iterator:
points = [list(map(int, x.split(','))) for x in s]
In action:
>>> s = ['3,4','4,5','6,5','7,8']
>>> points = [map(int, x.split(',')) for x in s]
>>> print(points)
[[3, 4], [4, 5], [6, 5], [7, 8]]
>>> s = ['3,4','4,5','6,5','7,8']
>>> from ast import literal_eval
>>> [literal_eval(x) for x in s]
[(3, 4), (4, 5), (6, 5), (7, 8)]
If you really need list of lists
>>> [list(literal_eval(x)) for x in s]
[[3, 4], [4, 5], [6, 5], [7, 8]]

Categories