Make all possible combinations of list elements - using python - python

I am trying to make all the possible combinations of a list.
like:
l= [1,4,6,8,11,13]
combL = [ [1],[4],[6],[8],[11],[13],[1,4], .. ]
I tried to use
itertools.combinations(l, len(l))
but it didn't work out. Any function on Python that do that ?

from itertools import combinations
def get_all_combinations(input_list):
for i in xrange(len(input_list)):
for item in combinations(input_list, r = i + 1):
yield list(item)
input_list = [1,4,6,8,11,13]
for item in get_all_combinations(input_list):
print item
We have created a generator, so it is efficient as we don't have to store the entire combinations in memory. It is important for a combinations generator, because, often the number of combinations is very big.
But if you want to get all the combinations as list, then you can do
list(get_all_combinations(input_list))
# [[1], [4], [6], [8], [11], [13], [1, 4], [1, 6], [1, 8], [1, 11], [1, 13],..]

as a list:
[i for j in xrange(len(l)) for i in itertools.combinations(l, j+1)]
or as a generator:
(i for j in xrange(len(l)) for i in itertools.combinations(l, j+1))

res = []
for L in range(0, len(l)+1):
for subset in itertools.combinations(l, L):
res.append(list(subset))
Output:
[[], [1], [4], [6], [8], [11], [13], [1, 4], [1, 6], [1, 8], [1, 11], [1, 13], [4, 6], [4, 8], [4, 11],....

Related

Creating multiple sublists in Python

I have a list J with len(J)=2. I want to create a sublist of each element in J[i] where i=0,1. I present the current and expected output.
J = [[1, 2, 4, 6, 7],[1,4]]
arJ1=[]
for i in range(0,len(J)):
J1=[J[i]]
arJ1.append(J1)
J1=list(arJ1)
print("J1 =",J1)
The current output is
J1 = [[[1, 2, 4, 6, 7], [1, 4]]]
The expected output is
J1 = [[[1], [2], [4], [6], [7]], [[1], [4]]]
you can try this,
J = [[1, 2, 4, 6, 7],[1,4]]
new_l = []
for l in J:
tmp = []
for k in l:
tmp.append([k])
new_l.append(tmp)
print(new_l)
this will give you
[[[1], [2], [4], [6], [7]], [[1], [4]]]
With simple list comprehension:
res = [[[i] for i in sub_l] for sub_l in J]
print(res)
[[[1], [2], [4], [6], [7]], [[1], [4]]]
You can do in one line with list comprehension:
[[[k] for k in l] for l in J]
J = [[1, 2, 4, 6, 7],[1,4]]
arJ1 = []
for in_list in J:
new_list = []
for x in in_list:
new_list.append([x])
arJ1.append(new_list)
print(arJ1)

generate combinations from list of numbers

generate all combinations from list of numbers,the combinations can be pair of two numbers
example 1 : list of 2 numbers [1,2]
[
[[1],[2]],
[[1,2]]
]
example 2 : list of 3 numbers [1,2,3]
[
[[1], [2], [3]],
[[1], [2, 3]],
[[1, 3], [2]],
[[1, 2], [3]]
]
example 3 : list of 4 numbers [1,2,3,4]
[
[[1], [2], [3], [4]]
[[1], [2], [3, 4]],
[[1], [2, 4], [3]],
[[1], [2, 3], [4]],
[[1, 4], [2], [3]],
[[1, 3], [2], [4]],
[[1, 2], [3], [4]],
[[1, 2], [3, 4]],
[[1, 3], [2, 4]],
[[1, 4], [2, 3]]
]
The current implementation works but it is slow for list of 10 numbers
def get_all_order_combinations(nums, first=True):
if first and len(nums) == 1:
return [[[nums[0]]]]
if len(nums) == 2:
nums.sort()
return [
[[nums[0]], [nums[1]]],
[[nums[0], nums[1]]]
]
else:
all_results = []
for i in range(0, len(nums)):
temp_list = list(nums)
del temp_list[i]
current_num = nums[i]
results = get_all_order_combinations(temp_list, False)
results = [[[current_num]]+result for result in results]
for result in results:
result.sort()
if result not in all_results:
all_results.append(result)
if len(nums) >= 4:
for comb in combinations(nums, 2):
comb = list(comb)
results = get_all_order_combinations(
[n for n in nums if n not in comb]
,False
)
results = [[comb]+result for result in results]
for result in results:
result.sort()
if result not in all_results:
all_results.append(result)
return all_results
Try using the python in-built "itertools" package.
It is optimised to create combinations, which may solve your concerns with speed. Online searches will yield results on how to use it.
Here is one example:
geeksforgeeks Permutation and Combination in Python with itertools
My attempt at reproducing example 2 using itertools:
from itertools import combinations
num_list = [1, 2, 3]
output_list = []
for i in range(1, len(num_list)):
comb = combinations(num_list, i)
obtained_combinations = []
for combination in list(comb):
if i != 1:
temp_list = num_list.copy()
for selected_number in combination:
temp_list.remove(selected_number)
obtained_combinations.append([temp_list, list(combination)])
else:
obtained_combinations.append(list(combination))
output_list.append(obtained_combinations)
print(output_list)
Output:
[[[1], [2], [3]], [[[3], [1, 2]], [[2], [1, 3]], [[1], [2, 3]]]]

How to get all consecutive sequences of numbers from given set of numbers?

I will start the description of the problem with an example so that the question is clear.
List of numbers: [1,2,3,4]
How can I get each successive string: [[1],[1,2],[1,2,3],[1,2,3,4],[2],[2,3],[2,3,4],[3],[3,4],[4]]
I've been trying to solve this problem for a while and managed to get [[1, 2, 3, 4], [2, 3, 4], [3, 4], [4]] with lots of useless repetitions.
list = [1,2,3,4]
i = 0
j = 0
tempList = []
sequancesList = []
while i < len(list):
while j < len(list):
tempList.append(list[j])
sequancesList.append(tempList)
j += 1
i += 1
j = i
tempList = []
def deleteDuplicates(list):
noduplist = []
for element in list:
if element not in noduplist:
noduplist.append(element)
return noduplist
finalSequancesList = deleteDuplicates(sequancesList)
print(finalSequancesList)
Here's how to do it:
list = [1,2,3,4]
sequancesList = []
for i in range(len(list)):
tmp = []
for j in range(i,len(list)):
tmp.append(list[j])
sequancesList.append(tmp[:])
print(sequancesList)
-> [[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [2], [2, 3], [2, 3, 4], [3], [3, 4], [4]]
Here is a generator that does exactly that:
def iter_successive(input_list):
for i in range(len(input_list)):
for j in range(i+1,len(input_list)+1):
yield input_list[i:j]
>>> list(iter_successive(input_list))
[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [2], [2, 3], [2, 3, 4], [3], [3, 4], [4]]
Comparable one-liner solution:
def iter_successive(input_list):
return (input_list[i:j] for i in range(len(input_list))
for j in range(i+1,len(input_list)+1))
Edit: As was stated in the comments, the approach below works only if the list contains whole, ascending numbers and not in other instances.
There are two ways to do this, either as a nested for-loop or a one-liner using list-comprehension. Both versions below:
Nested for-loop
nrs = list(range(1,5))
result = []
for i in nrs:
for j in range(i, max(nrs)+1):
result.append(list(range(i,j+1)))
print(result)
List-comprehension
result = [list(range(i,j+1)) for i in nrs for j in range(i, max(nrs)+1)]
print(result)

List all contiguous sub-arrays

I have an array [1, 2, 3] of integer and I need to return all the possible combination of contiguous sub-arrays of this array.
[[1],[2],[3],[1,2],[2,3],[1,2,3]]
How can I handle that with python? One way would be to have 2 loops and the array itself but there should be a better way.
One line solution (I don't know what means "better way" for you)
L = [1,2,3]
[L[i:i+j] for i in range(0,len(L)) for j in range(1,len(L)-i+1)]
L=[1,2,3,4]
[L[i:i+j] for i in range(0,len(L)) for j in range(1,len(L)-i+1)]
you get,
[[1], [1, 2], [1, 2, 3], [2], [2, 3], [3]]
[[1],
[1, 2],
[1, 2, 3],
[1, 2, 3, 4],
[2],
[2, 3],
[2, 3, 4],
[3],
[3, 4],
[4]]
Simplifying the Inspector's solution:
def getAllWindows(L):
for w in range(1, len(L)+1):
for i in range(len(L)-w+1):
yield L[i:i+w]
And a solution using no loops at all:
def allSubArrays(L,L2=None):
if L2==None:
L2 = L[:-1]
if L==[]:
if L2==[]:
return []
return allSubArrays(L2,L2[:-1])
return [L]+allSubArrays(L[1:],L2)
def kwindow(L, k):
for i in range(len(L)-k+1):
yield L[i:i+k]
def getAllWindows(L):
for w in range(1, len(L)+1):
yield from kwindow(L, w)
Ouput:
In [39]: for i in getAllWindows([1,2,3]): print(i)
[1]
[2]
[3]
[1, 2]
[2, 3]
[1, 2, 3]
An itertools based approach:
import itertools
def allSubArrays(xs):
n = len(xs)
indices = list(range(n+1))
for i,j in itertools.combinations(indices,2):
yield xs[i:j]
For example:
>>> list(allSubArrays([1,2,3]))
[[1], [1, 2], [1, 2, 3], [2], [2, 3], [3]]
li=[1,2,3]
l=[]
for i in range(length(li)):
for j in range(i,len(li)+1):
if i==j: *cancelling empty sublist item*
continue
else:
subli=li[i:j]
l.append(subli)
print(l)
output:
[[1], [1, 2], [1, 2, 3], [2], [2, 3], [3]]

Concatenate pairs of consecutive sublists in a list using Python

How would you combine sublists within a list by pairs?
For example with:
list1 = [[1,2,3],[4,5],[6],[7,8],[9,10]]
the result would be:
[[1,2,3,4,5],[6,7,8],[9,10]]
You could use zip_longest with a fill value (in case your list has an odd number of sublists) to zip an iterator over list1. Running a list comprehension over the zip generator object allows you to concatenate the consecutive pairs of lists:
>>> from itertools import zip_longest # izip_longest in Python 2.x
>>> x = iter(list1)
>>> [a+b for a, b in zip_longest(x, x, fillvalue=[])]
[[1, 2, 3, 4, 5], [6, 7, 8], [9, 10]]
Try using a list comprehension (but be careful with the indexes!). It works for lists with an even or odd number of sublists:
list1 = [[1, 2, 3], [4, 5], [6], [7, 8], [9, 10]]
n = len(list1)
[list1[i] + (list1[i+1] if i+1 < n else []) for i in xrange(0, n, 2)]
=> [[1, 2, 3, 4, 5], [6, 7, 8], [9, 10]]
list1=[[1,2,3],[4,5],[6],[7,8],[9,10]]
length = len(list1)
new_list = [ list1[i]+list1[i+1] if i+1 < length
else [list1[i]] for i in range(0,length,2) ]
print(new_list)
>>> list1=[[1,2,3],[4,5],[6],[7,8],[9,10]]
>>> list1
[[1, 2, 3], [4, 5], [6], [7, 8], [9, 10]]
Now we can do:
>>> test = [list1[0]+list1[1]]+[list1[2]+list1[3]]+list1[4]
>>> test
[[1, 2, 3, 4, 5], [6, 7, 8], 9, 10]
>>>
I am sure there is a better way, but this is the way I can think of!
list1 = [[1, 2, 3], [4, 5], [6], [7, 8], [9, 10]]
from itertools import islice, chain
print([list(chain.from_iterable(islice(list1, i, i + 2)))
for i in range(0, len(list1), 2)])
[[1, 2, 3, 4, 5], [6, 7, 8], [9, 10]]
Or without islice:
print([list(chain.from_iterable(list1[i:i+2]))
for i in range(0, len(list1), 2)])
[[1, 2, 3, 4, 5], [6, 7, 8], [9, 10]]
Use a simple loop:
list1=[[1,2,3],[4,5],[6],[7,8],[9,10]]
newlist = []
for i in range(0, len(list1), 2):
newlist.append(list1[i] + list1[i+1])
if len(list1) % 2 > 0:
newlist.append(list1[-1])
print newlist
Here is (I hope) a correct solution:
def pair_up(ls):
new_list = []
every_other1 = ls[::2]
every_other2 = ls[1::2]
for i in range(len(every_other2)):
new_list.append(every_other1[i]+every_other2[i])
if len(ls) % 2 == 1:
new_list.append(ls[-1])
return new_list
Working on same list with removing n-ths[-1] odd sublists:
for i in range(len(l)/2):#here we go only to last even item
l[i]+=l[i+1]#adding odd sublist to even sublist
l.pop(i+1)#removing even sublist

Categories

Resources