All supplementary subsets of a list in python [duplicate] - python

This question already has answers here:
How to get all subsets of a set? (powerset)
(32 answers)
Closed 5 years ago.
I am not sure if 'supplementary' is the right word, but I will explain my problem with an example. Let's say our list is:
[1,2,3,4]
What I am trying to find is:
[1], [2], [3], [4]
[1,2], [3], [4]
[1,3], [2], [4]
...
[1,2], [3,4]
[1,3], [2,4]
...
[1,2,3], [4]
[1,2,4], [3]
...
[1,2,3,4]
In other words, I try to get all lists such that they together have all elements of the initial list.
Thanks!

You could use Raymond Hettinger's partition recipe to find all partitions. I've modified it slightly to work with Python3. I also added partition_permutations to find the partitions of all permutations of the input, x.
import pprint
import itertools as IT
def partition(iterable, chain=IT.chain, map=map):
"""
http://code.activestate.com/recipes/576795/ (Raymond Hettinger)
>>> list(partition('abcd'))
[['abcd'],
['a', 'bcd'],
['ab', 'cd'],
['abc', 'd'],
['a', 'b', 'cd'],
['a', 'bc', 'd'],
['ab', 'c', 'd'],
['a', 'b', 'c', 'd']]
"""
s = iterable if hasattr(iterable, '__getitem__') else tuple(iterable)
n = len(s)
first, middle, last = [0], range(1, n), [n]
getitem = s.__getitem__
return [list(map(getitem, map(slice, chain(first, div), chain(div, last))))
for i in range(n) for div in IT.combinations(middle, i)]
def partition_permutations(iterable, ordered_partitions=False):
result = set()
for perm in IT.permutations(iterable):
for item in partition(perm):
if ordered_partitions:
result.add(tuple(item))
else:
result.add(tuple(sorted(item)))
result = [list(map(list, item)) for item in result]
result = sorted(result)
return result
x = [1,2,3,4]
result = partition_permutations(x, ordered_partitions=True)
pprint.pprint(result)
print(len(result))
yields 73 items:
[[[1], [2], [3], [4]],
[[1], [2], [3, 4]],
[[1], [2], [4, 3]],
[[1], [2, 3], [4]],
[[1], [2, 3, 4]],
[[1], [2, 4], [3]],
[[1], [2, 4, 3]],
[[1], [3], [4, 2]],
[[1], [3, 2], [4]],
[[1], [3, 2, 4]],
[[1], [3, 4, 2]],
[[1], [4, 2, 3]],
[[1], [4, 3, 2]],
[[1, 2], [3], [4]],
[[1, 2], [3, 4]],
[[1, 2], [4, 3]],
[[1, 2, 3], [4]],
[[1, 2, 3, 4]],
[[1, 2, 4], [3]],
[[1, 2, 4, 3]],
[[1, 3], [2], [4]],
[[1, 3], [2, 4]],
[[1, 3], [4, 2]],
[[1, 3, 2], [4]],
[[1, 3, 2, 4]],
[[1, 3, 4], [2]],
[[1, 3, 4, 2]],
[[1, 4], [2], [3]],
[[1, 4], [2, 3]],
[[1, 4], [3, 2]],
[[1, 4, 2], [3]],
[[1, 4, 2, 3]],
[[1, 4, 3], [2]],
[[1, 4, 3, 2]],
[[2], [3], [4, 1]],
[[2], [3, 1], [4]],
[[2], [3, 1, 4]],
[[2], [3, 4, 1]],
[[2], [4, 1, 3]],
[[2], [4, 3, 1]],
[[2, 1], [3], [4]],
[[2, 1], [3, 4]],
[[2, 1], [4, 3]],
[[2, 1, 3], [4]],
[[2, 1, 3, 4]],
[[2, 1, 4], [3]],
[[2, 1, 4, 3]],
[[2, 3], [4, 1]],
[[2, 3, 1], [4]],
[[2, 3, 1, 4]],
[[2, 3, 4, 1]],
[[2, 4], [3, 1]],
[[2, 4, 1], [3]],
[[2, 4, 1, 3]],
[[2, 4, 3, 1]],
[[3], [4, 1, 2]],
[[3], [4, 2, 1]],
[[3, 1], [4, 2]],
[[3, 1, 2], [4]],
[[3, 1, 2, 4]],
[[3, 1, 4, 2]],
[[3, 2], [4, 1]],
[[3, 2, 1], [4]],
[[3, 2, 1, 4]],
[[3, 2, 4, 1]],
[[3, 4, 1, 2]],
[[3, 4, 2, 1]],
[[4, 1, 2, 3]],
[[4, 1, 3, 2]],
[[4, 2, 1, 3]],
[[4, 2, 3, 1]],
[[4, 3, 1, 2]],
[[4, 3, 2, 1]]]
Note that partition_permutations treats the items inside each partition as
unordered. That is, for example, [[1,4], [2,3]] and [[2,3], [1,4]] are
treated as the same partition. If that is not what you want, then change
result = partition_permutations(x)
to
result = partition_permutations(x, ordered_partitions=True)

Related

cant store the value in global variable

Im trying to do permutation problem in leetcode with backtracking Algorithm, While Printing I got all the Possiblities but when i Trying to store those value in global variable I'm not allow to that
Ex:
AnswerIwant:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
when i print those value while recursion it is print
Example:
[1, 2, 3]
[1, 3, 2]
[2, 3, 1]
[2, 1, 3]
[3, 1, 2]
[3, 2, 1]
When I store The Value In Global variable for outPut I got like This
[1, 2, 3]
[[1, 2, 3]]
[[1, 2]]
[1, 3, 2]
[[1, 3, 2], [1, 3, 2]]
[[1, 3], [1, 3]]
[[1], [1]]
[2, 3, 1]
[[2, 3, 1], [2, 3, 1], [2, 3, 1]]
[[2, 3], [2, 3], [2, 3]]
[2, 1, 3]
[[2, 1, 3], [2, 1, 3], [2, 1, 3], [2, 1, 3]]
[[2, 1], [2, 1], [2, 1], [2, 1]]
[[2], [2], [2], [2]]
[3, 1, 2]
[[3, 1, 2], [3, 1, 2], [3, 1, 2], [3, 1, 2], [3, 1, 2]]
[[3, 1], [3, 1], [3, 1], [3, 1], [3, 1]]
[3, 2, 1]
[[3, 2, 1], [3, 2, 1], [3, 2, 1], [3, 2, 1], [3, 2, 1], [3, 2, 1]]
[[3, 2], [3, 2], [3, 2], [3, 2], [3, 2], [3, 2]]
[[3], [3], [3], [3], [3], [3]]
[[], [], [], [], [], []]
Here Is my code For the Above OutPut
nums = [1,2,3]
val=nums
answerIwant = []
numberOfValues=len(val)-1
answer=[]
def permutation(nums, bucket, index,sub):
global answerIwant,numberOfValues
for i in range(len(nums)):
val=nums.pop(0)
bucket.append(val)
if len(bucket)-1==numberOfValues:
print(bucket)
answerIwant.append(bucket)
permutation(nums, bucket, index,sub)
nev=bucket.pop()
nums.append(nev)
print(answerIwant)
#[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
sub=[]
bucket = []
val=(permutation(nums, bucket, index,sub))
print(val)
Explain that problem i'm facing with symbol word
Thank You
You have to append the copy of the list during appening in the answerIwant list. So you should replace answerIwant.append(bucket) to answerIwant.append(bucket.copy()).
Refer this for more info. So your code could be this,
nums = [1,2,3]
val=nums
answerIwant = []
numberOfValues=len(val)-1
answer=[]
def permutation(nums, bucket, index,sub):
global numberOfValues
for i in range(len(nums)):
val=nums.pop(0)
bucket.append(val)
if len(bucket)-1==numberOfValues:
# print(bucket)
answerIwant.append(bucket.copy())
permutation(nums, bucket, index,sub)
nev = bucket
nev=bucket.pop()
nums.append(nev)
#[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
sub=[]
bucket = []
permutation(nums, bucket, 0,sub)
print(answerIwant)

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

extract list pattern from list of list in python

I have a list of the form -
a_list = [[1, [2, 3, 4]], [2, [3, 4]], [3, [4]]]
I want to convert it to the form -
b_list = [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
Using the list comprehension, I have tried with below code
for lst in tup:
for lst1 in tup[1]:
tup2 = [lst[0],lst1]
and getting (which is wrong)-
tup2 = [3, [3, 4]]
Please help, Thanks in advance
Simple to do with a list comprehension:
a_list = [[1, [2, 3, 4]], [2, [3, 4]], [3, [4]]]
b_list = [[x,y] for [x,b] in a_list for y in b]
print(b_list)
result:
[[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]
using [x,b] unpacks the items into x as number and b as your list. Loop through elements of b and build the couples, flat-style.
You could try something like this , no matter how many int are there :
for sub_list in b:
for items in sub_list:
if isinstance(items, list):
track = sub_list.index(items)
first = sub_list[:track]
second = sub_list[track:][0]
import itertools
print([list(k) for k in itertools.product(first, second)])
test case:
b = [[1, [2, 3, 4]], [2, [3, 4]], [3, [4]]]
output:
[[1, 2], [1, 3], [1, 4]]
[[2, 3], [2, 4]]
[[3, 4]]
test case 2:
b=[[1,2,[2, 3, 4]], [2,3,5,6 ,[3, 4]], [3, [4]]]
output:
[[1, 2], [1, 3], [1, 4], [2, 2], [2, 3], [2, 4]]
[[2, 3], [2, 4], [3, 3], [3, 4], [5, 3], [5, 4], [6, 3], [6, 4]]
[[3, 4]]

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}

How to flatten a list in 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]]

Categories

Resources