I am want to achieve all possible combinations (w/o rearr.) of partitioning/breaking the string by k elements.
for example,
I have a string "abcd" and k=3, I want achieve the following,
if [a,b,c,d] and k=3 then return,
[ [ [a], [b], [c,d] ]
[ [a], [b,c], [d] ]
[ [a,b], [c], [d] ] ]
for example,
I have a string "abcde" and k=3, I want achieve the following,
if [a,b,c,d,e] and k=3 then return,
[ [ [a], [b], [c,d,e] ]
[ [a], [b,c,d], [e] ]
[ [a,b,c], [d], [e] ]
[ [a], [b,c], [d,e] ]
[ [a,b], [c], [d,e] ]
[ [a,b], [c,d], [e] ] ]
Note, that all the combinations have the a-b-c-d(-e) are in straight order i.e. without rearrangement.
Let's say there's a function "breaklist" which does the work, takes the list and breaks it into k elements of the combination of the elements in the list (w/o rearr.) and finally, returns me a three-dimensional array.
def breakList(l: list, k: int):
...
return partitionedList
My Logic:
Let's say the size of the string be, "z=len(string)" and "k" be an integer by which the string is to be divided.
Now by observation, the maximum size of a element of the combination is "z-k+1", let that be n.
Now start from the first index, go till "n" and the rest by "j=1" then saves in a 3D Array.
Next iteration, will be the same by decrement of n by 1 i.e. "n-1" and the rest by "j=2" then saves to the 3D Array.
Next iteration, will decrement n by another 1 i.e. "(n-1)-1" and the rest by "j=3" then saves to the 3D Array.
"j" runs till "n", and, "n" runs to 1
This gives all the combination w/o rearrangement.
But this is not the most efficient approach I came up with, and at the same time it makes the task somewhat complex and time-consuming.
So, is there any better approach (I know there is...)? and also can I simplify the code (in terms of number of lines of codes) by using python3?
There's a better way... As mentioned in the referenced question, you just need to re-focus your thinking on the slice points. If you want 3 segments, you need 2 partitions. These partitions are all of the possible combinations of index positions between [1, end-1]. Sounds like a job for itertools.combinations!
This is only a couple lines of code, with the most complicated piece being the printout, and if you don't need to print, it gets easier.
from itertools import combinations as c
data = list('abcdefg')
k = 3
slice_point_sets = c(range(1, len(data)), k-1)
# do the slicing
for point_set in slice_point_sets:
start = 0
for end in point_set:
print(data[start:end], end=',')
start = end
print(data[end:])
# or pop it into a 3d array...
slice_point_sets = c(range(1, len(data)), k-1)
result = []
for point_set in slice_point_sets:
sublist = []
start = 0
for end in point_set:
sublist.append(data[start:end])
start = end
sublist.append(data[end:])
result.append(sublist)
Output:
['a'],['b'],['c', 'd', 'e', 'f', 'g']
['a'],['b', 'c'],['d', 'e', 'f', 'g']
['a'],['b', 'c', 'd'],['e', 'f', 'g']
['a'],['b', 'c', 'd', 'e'],['f', 'g']
['a'],['b', 'c', 'd', 'e', 'f'],['g']
['a', 'b'],['c'],['d', 'e', 'f', 'g']
['a', 'b'],['c', 'd'],['e', 'f', 'g']
['a', 'b'],['c', 'd', 'e'],['f', 'g']
['a', 'b'],['c', 'd', 'e', 'f'],['g']
['a', 'b', 'c'],['d'],['e', 'f', 'g']
['a', 'b', 'c'],['d', 'e'],['f', 'g']
['a', 'b', 'c'],['d', 'e', 'f'],['g']
['a', 'b', 'c', 'd'],['e'],['f', 'g']
['a', 'b', 'c', 'd'],['e', 'f'],['g']
['a', 'b', 'c', 'd', 'e'],['f'],['g']
I think this could work:
Get all possible sum partitions of the len(your_list).
Filter them by len(partition) == k.
Get the itertools.permutations by k elements of all this partitions.
Now you have list of lists like this: [(1, 1, 2), (1, 2, 1), (1, 1, 2), (1, 2, 1), (2, 1, 1), (2, 1, 1)]
Clean up this list of duplicates (make the set):
{(1, 2, 1), (2, 1, 1), (1, 1, 2)}
For each permutation pick exact number elements from your_list:
(1, 1, 2) -> [[a], [b], [c, d]],
(1, 2, 1) -> [[a], [b, c], [d]],
and so on..
Code
import itertools as it
start_list = ['a', 'b', 'c', 'd', 'e']
k = 3
def partitions(n, k=None): # step 1 function
if k is None:
k = n
if n == 0:
return []
return ([[n]] if n<=k else []) + [
l + [i]
for i in range(1, 1+min(n, k))
for l in partitions(n-i, i)]
final_list = []
partitions = filter(lambda x: len(x)==k, partitions(len(start_list))) # step 1-2
for partition in partitions:
pickings = set(it.permutations(partition, k)) # step 3-5
for picking in pickings:
temp = []
i = 0
for e in picking: # step 6
temp.append(start_list[i:i+e])
i += e
final_list.append(temp)
print(*final_list, sep='\n')
I have two lists:
list1 = ["a","e","d","c","f","g"]
list2 = ["a","c","d","f"]
In this the list1 cannot be sorted and should be retained as is. I am trying to sort the list2 exactly in the same order as list1 and get the missing values from list1 that exists between the first and last value of list2.
For example, if I sort list2 as according to list1using the following code,
list2 = [x for _, x in sorted(zip(list1,list2))]
I get the following index based sorted list:
list2 = ['a', 'f', 'd', 'c']
However the desired output is
list2 = ['a','d','c','f']
How can I sort the list2 according to the list1 taking the literal sequence of elements and not the index position based sorting.
It might not be the most efficient, and it doesn't cope with duplicates, but the following list comprehension should do what you want:
list1 = ["a","e","d","c","f","g"]
list2 = ["a","c","d","f"]
print([x for x in list1 if x in list2])
['a', 'd', 'c', 'f']
It walks list1, using the item if it is found in list2.
I need to convert a single input string into a dictionary with its place indices as keys and the letters as values in python. But I'm stuck here. Any help will be appreciated.
r = list("abcdef")
print (r)
for index,char in enumerate(r,0):
indd = str(index)
print(indd)
abc = indd.split(",")
list2 = list(abc)
d = dict(zip(list2,r))
print(d)
This is one approach using range.
Demo:
r = list("abcdef")
d = {}
for i in range(len(r)):
d[i] = r[i]
print(d)
Output:
{0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', 5: 'f'}
Or a simpler approach using dict().
r = list("abcdef")
d = dict(zip(range(len(r)), r))
print(d)
You have a string abcdef.
First make a list of tuples having first element of tuple as place index and second element of the tuple as the letter at that index. This can be done in this way:
tuples = list(enumerate("abcdef"))
Now, using the dictionary constructor, convert this list of tuples to a dictionary as given below:
dict(tuples)
Demo:
>>> dict(list(enumerate("abcdef")))
{0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', 5: 'f'}