Removing permutations from a list - python-3.x

I am trying to remove duplicates from a list of permutations to just leave the combinations , the list of number is as follows:
[[1, 3, 11, 13], [1, 7, 11, 9], [1, 9, 11, 7], [1, 15, 9, 3], [3, 1, 11, 13], [3, 5, 11, 9], [3, 15, 9, 1], [5, 3, 11, 9], [5, 11, 9, 3], [5, 13, 9, 1], [7, 1, 11, 9], [7, 11, 9, 1], [9, 1, 11, 7], [11, 5, 9, 3], [11, 7, 9, 1], [13, 5, 9, 1], [15, 1, 9, 3], [15, 3, 9, 1]]
Here is a method I have made but none of the list being printed is empty :
def permtocomb(fcombs):
fcombinations=fcombs
global value
global comp
global count
global combs
global b
for z in range(0,len(fcombinations)):
count = 0
print('testing array'+str(fcombinations[z]))
for x in range(0,4):
value=fcombinations[z][x]
for j in range(0,len(fcombinations)):
print('against arrqay'+str(fcombinations[j]))
for v in range(0,4):
if value==fcombinations[j][v]:
count+=1
b=j
if count<=3:
#fcombinations.pop(fcombinations[c])
combs.append(fcombinations[b])
permtocomb(fcombinations)
print(fcombinations)
print(combs)
Are there any python plugins or builtins capable of removing permutations just leaving the combinations?

It is usually a bad idea to use global variables as it makes debugging very hard.
Here's a very simple way to do this, just keep a record of what you have seen. You can use set to ignore combinations but sets are unhashable so you can use frozensets, e.g.:
In []:
data = [[1, 3, 11, 13], ...]
seen = set()
result = []
for d in data:
if frozenset(d) not in seen:
result.append(d)
seen.add(frozenset(d))
result
Out[]:
[[1, 3, 11, 13], [1, 7, 11, 9], [1, 15, 9, 3], [3, 5, 11, 9], [5, 13, 9, 1]]
If you don't care about order this can be simplified:
In []:
[list(e) for e in set(frozenset(d) for d in data)]
Out[]:
[[1, 11, 9, 7], [11, 1, 3, 13], [9, 13, 5, 1], [1, 3, 9, 15], [11, 9, 3, 5]]
However, if you really don't care about order you may want to just leave it as a set of frozensets:
set(frozenset(d) for d in data)
Note: This assumes there are no duplicate values in each of your elements (which your example data doesn't have), if you do have multiple values you will need to switch to multisets (collections.Counter()).

Related

Get Specific Element from a 2d List Using Condition

Here is a list.
list=[[[5, 1, 50], [7, 10, 52], 2], [[7, 10, 52], [10, 5, 163], 3], [[10, 5, 163], [13, 9, 85], 3], [[13, 9, 85], [14, 3, 176], 1], [[14, 3, 176], [15, 7, 96], 1]]
I want to retrieve an element from the list based on the minimum value which are 2,3,3,1,1 or we can say list[i][j]. From these element I want to find the minimum which is 1 and from that I want to retrieve the element [[[13, 9, 85], [14, 3, 176], 1]]. As here two 1 exist, indexwise I am choosing first one.
Can you tell me how can I do the code?
Sorry for being noob.
Just use find minimum concept with O(N)
list1=[[[5, 1, 50], [7, 10, 52], 2], [[7, 10, 52], [10, 5, 163], 3], [[10, 5, 163], [13, 9, 85], 3], [[13, 9, 85], [14, 3, 176], 1], [[14, 3, 176], [15, 7, 96], 1]]
# Assign first element as a minimum.
min1 = list1[0][2]
minIx = 0;
for i in range(len(list1)):
# If the other element is less than min element
if list1[i][2] < min1:
min1 = list1[i][2] #It will change
minIx = i
print("The smallest element in the list is ",list1[minIx])

Transponse a list of lists from 2nd element in python

list_of_lists = [[1, 2, 3, 4], [1, 5, 6, 7], [1, 8, 9, 10]]
I would like to get to:
transposed_list = [[1, 2, 5, 8], [1, 3, 6, 9], [1, 4, 7, 10]]
In other words, only transpose from the 2nd element in the list, keeping the first element in place.
Try:
list_of_lists = [[1, 2, 3, 4], [1, 5, 6, 7], [1, 8, 9, 10]]
out = [
[list_of_lists[i][0]] + list(l)
for i, l in enumerate(zip(*(l[1:] for l in list_of_lists)))
]
print(out)
Prints:
[[1, 2, 5, 8], [1, 3, 6, 9], [1, 4, 7, 10]]

How do I create a new list based on multiple lists within a dictionary?

I am trying to define a function that takes a dictionary with multiple lists as values and creates a new list for each index position. I am able to do it one at a time with my current function. But would like to make it so all lists are created with one function call. Thanks for any help :)
league_standings = {'Brett': [9, 6, 7, 8, 3, 7, 7, 5], 'Matt B': [6, 3, 6, 3, 8, 11, 10, 8],
'Will/Derek': [6, 7, 8, 7, 6, 6, 4, 6], 'Bryan': [5, 6, 6, 7, 11, 6, 6, 6],
'Sean': [11, 9, 7, 6, 2, 3, 5, 6], 'Joey/Brian': [4, 4, 4, 3, 6, 8, 8, 6],
'Tim': [4, 8, 10, 3, 6, 5, 8, 8], 'Adam': [3, 7, 3, 10, 10, 6, 3, 4],
'Michael': [7, 9, 6, 8, 6, 9, 10, 5], 'James/Adam': [9, 5, 6, 6, 9, 3, 7, 8],
'John': [8, 7, 9, 7, 4, 9, 6, 8], 'Matt R': [6, 7, 6, 10, 10, 5, 4, 8]}
def elim_px(player_dict):
season = []
for k,v in player_dict.items():
season.append(v[0])
ss = sorted(season)
bottom_four = ss[:4]
print(bottom_four)
stinkers= []
for k,v in player_dict.items():
for i in bottom_four:
if k in stinkers:
continue
elif i == v[0]:
stinkers.append(k)
print(stinkers)

Remove nested list if nested list contains a number at an index

I want to remove a nested list of numbers if that nested list contains a specific number at a specific index.
Sample list of lists:
permutations_list = [[9, 7, 14, 4, 2, 10], [9, 7, 2, 10, 14, 4], [9, 7, 2, 10, 4, 14], [9, 7, 2, 14, 10, 4], [9, 7, 2, 14, 4, 10], [9, 7, 2, 4, 10, 14], [9, 7, 2, 4, 14, 10], [9, 7, 4, 10, 14, 2], [9, 7, 4, 10, 2, 14], [9, 7, 4, 14, 10, 2], [9, 7, 4, 14, 2, 10], [9, 7, 4, 2, 10, 14], [9, 7, 4, 2, 14, 10]]
What I would like is to check if each nested list contains the number 14 at index 4. If that occurs, remove any nested list that meets those specifications resulting in the following list of lists:
permutations_list = [[9, 7, 14, 4, 2, 10], [9, 7, 2, 10, 4, 14], [9, 7, 2, 14, 10, 4], [9, 7, 2, 14, 4, 10], [9, 7, 2, 4, 10, 14], [9, 7, 4, 10, 2, 14], [9, 7, 4, 14, 10, 2], [9, 7, 4, 14, 2, 10], [9, 7, 4, 2, 10, 14]]
Here's what I tried:
for i in permutations_list:
for c in i:
if c =='10' and c[4]:
permutations_list.remove(i)
All this does is result in:
TypeError: 'int' object is not subscriptable
Using a list comprehension
Ex:
permutations_list = [[9, 7, 14, 4, 2, 10], [9, 7, 2, 10, 14, 4], [9, 7, 2, 10, 4, 14], [9, 7, 2, 14, 10, 4], [9, 7, 2, 14, 4, 10], [9, 7, 2, 4, 10, 14], [9, 7, 2, 4, 14, 10], [9, 7, 4, 10, 14, 2], [9, 7, 4, 10, 2, 14], [9, 7, 4, 14, 10, 2], [9, 7, 4, 14, 2, 10], [9, 7, 4, 2, 10, 14], [9, 7, 4, 2, 14, 10]]
permutations_list = [i for i in permutations_list if not i[4] == 14]
print(permutations_list)
Or using filter
permutations_list = list(filter(lambda x: x[4] != 14, permutations_list))
Output:
[[9, 7, 14, 4, 2, 10],
[9, 7, 2, 10, 4, 14],
[9, 7, 2, 14, 10, 4],
[9, 7, 2, 14, 4, 10],
[9, 7, 2, 4, 10, 14],
[9, 7, 4, 10, 2, 14],
[9, 7, 4, 14, 10, 2],
[9, 7, 4, 14, 2, 10],
[9, 7, 4, 2, 10, 14]]
you can just loop through the main list once and check if the element at index 4 in this list is 14 or not. if it is 14, remove it, if not, do nothing. like I did below
for i in permutations_list :
if i[4] == 14 :
permutations_list.remove(i)

How can I have a python function that effectively divide a list to all possible number of chunks?

I want to split a list (float or integer) according to the following conditions:
Splitting the list into all possible subsamples.
No duplication.
A unit sample cannot be a subsample.
I have what splits a list into equal sizes by giving the number of subsamples.
The code I have laid my hand on which worked but does not give me what I want
import numpy as np
x = [1,2,3,4,5,6,7,8,9,10]
l = np.array_split(x,3)
output
[[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]]
I desire to have a list of subsample of all possibilities without duplication. that is, a combination of all unique possibilities when the list is split into 2, 3, 4, etc (no two or more subsamples will have the same element)).
I do not what to specify chunk number so that it will not be limited to such number.
Here is what I did manually
From the following series [1,2,3,4,5,6,7,8,9,10] I sliced it into all possible blocks as follows:
when splitting into 2
[1][2,3,4,5,6,7,8,9,10]
[1,2][3,4,5,6,7,8,9,10]
[1,2,3][4,5,6,7,8,9,10]
[1,2,3,4][5,6,7,8,9,10]
[1,2,3,4,5][6,7,8,9,10]
[1,2,3,4,5,6][7,8,9,10]
[1,2,3,4,5,6,7,8][9,10]
[1,2,3,4,5,6,7,8,9][10]
when splitting into 3
[1][2][3,4,5,6,7,8,9,10]
[1][2,3][4,5,6,7,8,9,10]
[1][2,3,4][5,6,7,8,9,10]
[1][2,3,4,5][6,7,8,9,10]
[1][2,3,4,5,6][7,8,9,10]
[1][2,3,4,5,6,7][8,9,10]
[1][2,3,4,5,6,7,8][9,10]
[1][2,3,4,5,6,7,8,9][10]
[1,2][3][4,5,6,7,8,9,10]
[1,2][3,4][5,6,7,8,9,10]
[1,2][3,4,5][6,7,8,9,10]
[1,2][3,4,5,6][7,8,9,10]
[1,2][3,4,5,6,7][8,9,10]
[1,2][3,4,5,6,7,8][9,10]
[1,2][3,4,5,6,7,8,9][10]
[1,2,3][4][5,6,7,8,9,10]
[1,2,3][4,5][6,7,8,9,10]
[1,2,3][4,5,6][7,8,9,10]
[1,2,3][4,5,6,7][8,9,10]
[1,2,3][4,5,6,7,8][9,10]
[1,2,3][4,5,6,7,8,9][10]
[1,2,3,4][5][6,7,8,9,10]
[1,2,3,4][5,6][7,8,9,10]
[1,2,3,4][5,6,7][8,9,10]
[1,2,3,4][5,6,7,8][9,10]
[1,2,3,4][5,6,7,8,9][10]
[1,2,3,4,5][6][7,8,9,10]
[1,2,3,4,5][6,7][8,9,10]
[1,2,3,4,5][6,7,8][9,10]
[1,2,3,4,5][6,7,8,9][10]
[1,2,3,4,5,6][7][8,9,10]
[1,2,3,4,5,6][7,8][9,10]
[1,2,3,4,5,6][7,8,9][10]
when splitting into 4
[1,2,3,4,5,6,7][8][9,10]
[1,2,3,4,5,6,7][8,9][10]
[1,2,3,4,5,6,7,8][9][10]
After all possible splitting into blocks, I removed all the single digit blocks and also removed all duplicated blocks.
[2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9]
[3,4,5,6,7,8,9,10]
[2,3]
[2,3,4]
[2,3,4,5]
[2,3,4,5,6]
[2,3,4,5,6,7]
[2,3,4,5,6,7,8]
[2,3,4,5,6,7,8,9]
[4,5,6,7,8,9,10]
[3,4]
[3,4,5]
[3,4,5,6]
[3,4,5,6,7]
[3,4,5,6,7,8]
[1,2][3,4,5,6,7,8,9]
[5,6,7,8,9,10]
[4,5]
[4,5,6]
[4,5,6,7]
[4,5,6,7,8]
[1,2,3][4,5,6,7,8,9]
[6,7,8,9,10]
[5,6]
[5,6,7]
[5,6,7,8]
[1,2,3,4][5,6,7,8,9]
[1,2,3,4,5][7,8,9,10]
[6,7]
[6,7,8]
[6,7,8,9]
[8,9,10]
[7,8]
[1,2,3,4,5,6][7,8,9]
[9,10]
[1,2,3,4,5,6,7][8,9]
[1,2,3,4,5,6,7,8]
Here, I gather all the possible chunks together.
This is what I desire as an output.
[[2,3,4,5,6,7,8,9,10], [1,2,3,4,5,6,7,8,9], [3,4,5,6,7,8,9,10], [2,3], [2,3,4], [2,3,4,5], [2,3,4,5,6], [2,3,4,5,6,7], [2,3,4,5,6,7,8], [2,3,4,5,6,7,8,9], [4,5,6,7,8,9,10],[3,4], [3,4,5], [3,4,5,6], [3,4,5,6,7], [3,4,5,6,7,8], [1,2], [3,4,5,6,7,8,9], [5,6,7,8,9,10], [4,5], [4,5,6], [4,5,6,7], [4,5,6,7,8], [1,2,3], [4,5,6,7,8,9], [6,7,8,9,10], [5,6], [5,6,7], [5,6,7,8], [1,2,3,4], [5,6,7,8,9], [1,2,3,4,5], [7,8,9,10], [6,7], [6,7,8], [6,7,8,9], [8,9,10], [7,8], [1,2,3,4,5,6], [7,8,9], [9,10], [1,2,3,4,5,6,7], [8,9], [1,2,3,4,5,6,7,8]]
It looks to me like the problem reduces to finding all substrings of length 2 or greater that leave at least one fragment of length 1. In other words, you won't have to enumerate every partition to find them.
def parts(thing):
result = []
for i in range(len(thing)):
for j in range(i + 1, len(thing) + 1):
if 1 < len(thing[i:j]) < len(thing):
result.append(thing[i:j])
return result
res = parts([*range(1,11)])
# res
# [[1, 2], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 6],
# [1, 2, 3, 4, 5, 6, 7], [1, 2, 3, 4, 5, 6, 7, 8],
# [1, 2, 3, 4, 5, 6, 7, 8, 9], [2, 3], [2, 3, 4], [2, 3, 4, 5],
# [2, 3, 4, 5, 6], [2, 3, 4, 5, 6, 7], [2, 3, 4, 5, 6, 7, 8],
# [2, 3, 4, 5, 6, 7, 8, 9], [2, 3, 4, 5, 6, 7, 8, 9, 10], [3, 4], [3, 4, 5],
# [3, 4, 5, 6], [3, 4, 5, 6, 7], [3, 4, 5, 6, 7, 8], [3, 4, 5, 6, 7, 8, 9],
# [3, 4, 5, 6, 7, 8, 9, 10], [4, 5], [4, 5, 6], [4, 5, 6, 7], [4, 5, 6, 7, 8],
# [4, 5, 6, 7, 8, 9], [4, 5, 6, 7, 8, 9, 10], [5, 6], [5, 6, 7], [5, 6, 7, 8],
# [5, 6, 7, 8, 9], [5, 6, 7, 8, 9, 10], [6, 7], [6, 7, 8], [6, 7, 8, 9],
# [6, 7, 8, 9, 10], [7, 8], [7, 8, 9], [7, 8, 9, 10], [8, 9], [8, 9, 10],
# [9, 10]]

Resources