How to flatten a list in python? - python

I have a program which outputs solutions, which are lists of numbers as such:
[[1, [[1, 5], [2, 4], [3, 3], [4, 2], [5, 1]]], [2, [[1, 4], [2, 3], [3, 2], [4, 1]]], [3, [[1, 3], [2, 2], [3, 1]]], [4, [[1, 2], [2, 1]]], [5, [[1, 1]]]]
What I want this to be turned into is:
[[1,1,5],[1,2,4],[1,3,3],[1,4,2],[1,5,1],[2,1,4],[2,2,3],[2,3,2],[2,4,1],[3,1,3],[3,2,2],[3,3,1],[4,1,2],[4,2,1],[5,1,1]]
Basically, each term in the whole list is headed by a number, which forms the first item of all possible solutions with that number, and then the following lists indicate what is to be added.

This should work. It works with the example that you have atleast.
result = [[[i[0]] + j for j in i[1:][0] ] for i in arr][0]

items = [[1, [[1, 5], [2, 4], [3, 3], [4, 2], [5, 1]]], [2, [[1, 4], [2, 3], [3, 2], [4, 1]]], [3, [[1, 3], [2, 2], [3, 1]]], [4, [[1, 2], [2, 1]]], [5, [[1, 1]]]]
flat_items = []
for item in items:
leading = item[0]
for i in item[1]:
flat_items.append([leading]+i)
print(flat_items)

Yet another solution that gives you an output as you needed:
def flatten(lst):
result = []
for i in lst:
for j in i[1]:
pair = j[:]
pair.insert(0, i[0])
result.append(pair)
return result

Introduce two functions: merge and flatten.
The second function is taken from here:
def flatten(lst):
return [item for sublist in lst for item in sublist]
The first function is defined as:
def merge(lst):
return [[lst[0]] + x for x in flatten(lst[1:])]
Then call them:
s = [[1, [[1, 5], [2, 4], [3, 3], [4, 2], [5, 1]]], [2, [[1, 4], [2, 3], [3, 2], [4, 1]]], [3, [[1, 3], [2, 2], [3, 1]]], [4, [[1, 2], [2, 1]]], [5, [[1, 1]]]]
print flatten([merge(x) for x in s])
Output is:
[[1, 1, 5], [1, 2, 4], [1, 3, 3], [1, 4, 2], [1, 5, 1], [2, 1, 4], [2, 2, 3], [2, 3, 2], [2, 4, 1], [3, 1, 3], [3, 2, 2], [3, 3, 1], [4, 1, 2], [4, 2, 1], [5, 1, 1]]

Related

List all combinations of 3 equally sized partitions of a list

I have a vector containing 15 values and would like to find all the possible ways to partition the vector into 3 equally sized partitions. I know there is n!/(n-r)!r! combinations to take r values out of a list of n values with replacement & this is easily generated with itertools in Python.
Does there exist an easy solution to list all combinations in this case as well?
Mathematically there will be n!/((n/3!)^3)/3! solutions, for example if n=15 there will be 126126 combinations and if n=6 there will be 15 combinations.
As the task needs to remove duplicates, which is not supported by itertools, I would recommend package more_itertools:
import more_itertools
n = 6
assert n%3 == 0
[x for x in more_itertools.set_partitions(range(n), 3) if len(x[0]) == len(x[1]) == len(x[2])]
[[[0, 1], [2, 3], [4, 5]],
[[0, 1], [3, 4], [2, 5]],
[[0, 1], [2, 4], [3, 5]],
[[1, 2], [0, 3], [4, 5]],
[[0, 2], [1, 3], [4, 5]],
[[1, 2], [3, 4], [0, 5]],
[[0, 2], [3, 4], [1, 5]],
[[1, 2], [0, 4], [3, 5]],
[[0, 2], [1, 4], [3, 5]],
[[2, 3], [1, 4], [0, 5]],
[[2, 3], [0, 4], [1, 5]],
[[1, 3], [2, 4], [0, 5]],
[[0, 3], [2, 4], [1, 5]],
[[1, 3], [0, 4], [2, 5]],
[[0, 3], [1, 4], [2, 5]]]

How can I sort the lists in the list?

I'd like to know how to sort the lists in the list. However, I don't want to align by key. I'd like to change it according to the following method.
arr = [[2, 3], [5, 1], [4, 1], [5, 3], [4, 2]]
# solution...
I_want_arr = [[2, 3], [1, 5], [1, 4], [3, 5], [2, 4]]
i tried it
for i in arr:
i.sort()
but, it didn't work
using list comprehenstion:
arr = [[2, 3], [5, 1], [4, 1], [5, 3], [4, 2]]
sorted_output = [sorted(l) for l in arr]
using map():
sorted_output = list(map(sorted, arr))
#Gabip's solution includes this and a more time efficient one, check that out first!
How about
arr = [[2, 3], [5, 1], [4, 1], [5, 3], [4, 2]]
I_want_arr = [sorted(x) for x in arr]
This outputs
[[2, 3], [1, 5], [1, 4], [3, 5], [2, 4]]

combinations of list repeated N times python

I have a list l = [1, 2, 3, 4, 5] and would like to generate all possible combinations assuming the elements of l are repeated N times.
Example:
[1, 2, 3, 4, 5] with N = 2 would yield
[1, 1], [1, 2], [1, 3], [1, 4], [1, 5]
[2, 1], [2, 2], [2, 3], [2, 4], [2, 5]
[3, 1], [3, 2], [3, 3], [3, 4], [3, 5]
[4, 1], [4, 2], [4, 3], [4, 4], [4, 5]
[5, 1], [5, 2], [5, 3], [5, 4], [5, 5]
Thanks!
You want itertools.product:
>>> from itertools import product
>>> list(map(list, product([1, 2, 3, 4, 5], repeat=2)))
[[1, 1], [1, 2], [1, 3], [1, 4], [1, 5], [2, 1], [2, 2], [2, 3], [2, 4], [2, 5], [3, 1], [3, 2], [3, 3], [3, 4], [3, 5], [4, 1], [4, 2], [4, 3], [4, 4], [4, 5], [5, 1], [5, 2], [5, 3], [5, 4], [5, 5]]

counting frequency in list

I have a list of lists:
countall = [[5, 0], [4, 1], [4, 1], [3, 2], [4, 1], [3, 2], [3, 2], [2, 3], [4, 1], [3, 2], [3, 2], [2, 3], [3, 2], [2, 3], [2, 3], [1, 4], [4, 1], [3, 2], [3, 2], [2, 3], [3, 2], [2, 3], [2, 3], [1, 4], [3, 2], [2, 3], [2, 3], [1, 4], [2, 3], [1, 4], [1, 4], [0, 5]]
I would like to find the frequency of sub-lists in the above list.
I have tried to use itertools:
freq = [len(list(group)) for x in countall for key, group in groupby(x)]
However, I am getting the wrong results:
[1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1]
What is wrong with my list comprehension?
Groupby seems to deal with sequences that come after each other. To use it you would need to sort the list first. Another option is to use the Counter class:
from collections import Counter
countall = [[5, 0], [4, 1], [4, 1], [3, 2], [4, 1], [3, 2], [3, 2], [2, 3], [4, 1], [3, 2], [3, 2], [2, 3], [3, 2], [2, 3], [2, 3], [1, 4], [4, 1], [3, 2], [3, 2], [2, 3], [3, 2], [2, 3], [2, 3], [1, 4], [3, 2], [2, 3], [2, 3], [1, 4], [2, 3], [1, 4], [1, 4], [0, 5]]
Counter([tuple(x) for x in countall])
Output:
Counter({(3, 2): 10, (2, 3): 10, (1, 4): 5, (4, 1): 5, (5, 0): 1, (0, 5): 1})
as pointed by ForceBru first sort your list then use groupby:
from itertools import groupby
countall = [[5, 0], [4, 1], [4, 1], [3, 2], [4, 1], [3, 2], [3, 2], [2, 3], [4, 1], [3, 2], [3, 2], [2, 3], [3, 2], [2, 3], [2, 3], [1, 4], [4, 1], [3, 2], [3, 2], [2, 3], [3, 2], [2, 3], [2, 3], [1, 4], [3, 2], [2, 3], [2, 3], [1, 4], [2, 3], [1, 4], [1, 4], [0, 5]]
freq = [(key, len(list(x))) for key, x in groupby(sorted(countall))]
print(freq)
output:
[([0, 5], 1), ([1, 4], 5), ([2, 3], 10), ([3, 2], 10), ([4, 1], 5), ([5, 0], 1)]
your code has bugs:
freq = [len(list(group)) for x in countall for key, group in groupby(x)]
^paranthesis missing
Then you are grouping each individual list in countall which is not needed.
for x in countall for key, group in groupby(x)
yo can directly groupby on sorted(countall)
Also, as answered by #Bemmu you can use collections.Counter. But that does not support list so first you will have to convert your data to tupple or string then use Counter
As noted in comments you will need to sort if you are using groupby.
Code:
import itertools as it
freq = {tuple(key): len(list(group)) for key, group in it.groupby(sorted(countall))}
Test Code:
countall = [[5, 0], [4, 1], [4, 1], [3, 2], [4, 1], [3, 2], [3, 2], [2, 3],
[4, 1], [3, 2], [3, 2], [2, 3], [3, 2], [2, 3], [2, 3], [1, 4],
[4, 1], [3, 2], [3, 2], [2, 3], [3, 2], [2, 3], [2, 3], [1, 4],
[3, 2], [2, 3], [2, 3], [1, 4], [2, 3], [1, 4], [1, 4], [0, 5]]
print(freq)
Results:
{(3, 2): 10, (1, 4): 5, (2, 3): 10, (5, 0): 1, (0, 5): 1, (4, 1): 5}

declaring and initialising 2d array in python

I am declaring multidimensional array in python
Nbrs[23][2] = [[1, 1], [1, 2], [2, 1],
[2, 3], [3, 2], [1, 3],
[3, 1], [1, 4], [3, 4],
[4, 3], [4, 1], [1, 5],
[2, 5], [3, 5], [4, 5],
[5, 4], [5, 3], [5, 2],
[5, 1], [1, 6], [5, 6],
[6, 5], [6, 1]
]
It gives me error as:
NameError: name 'Nbrs' is not defined
I cannot declare 2 dimensional array in python by this way?
Assignment statement:
Nbrs[23][2] = [[1, 1], [1, 2], [2
# ^ ^ you can't index Nbrs before it created
should be:
Nbrs = [[1, 1], [1, 2], [2
# now after this statement, Nbrs a list of list you can access
# its elements useng `Nbrs[i][j]` for i < len(Nbrs) and j < 2
I think you confuses because of C, C++ declarations!
You don't need to specify the dimensions when defining lists in python. When you type Nbrs[23][2] python is trying to find what's at [23][2] in Nbrs but in this case Nbrs doesn't exist because you are trying to define it for the first time here.
Instead do this:
Nbrs = [[1, 1], [1, 2], [2, 1], ....
That's not the right syntax. You don't need to include anything about the variable's type on the left-hand side; in particular, drop the dimensions.
Nbrs = [[1, 1], [1, 2], [2, 1], [2, 3], [3, 2], [1, 3], [3, 1], [1, 4], [3, 4], [4, 3], [4, 1], [1, 5], [2, 5], [3, 5], [4, 5], [5, 4], [5, 3], [5, 2], [5, 1], [1, 6], [5, 6], [6, 5], [6, 1]]
What you've written tries to assign to an element of Nbrs, which doesn't exist yet.

Categories

Resources