Finding all possible combination of placement of array by switching [duplicate] - python

This question already has answers here:
Running through combinations of 4 numbers
(2 answers)
Closed 1 year ago.
How to find all possible of array switching?
Example
Original Value: [10,5,3,6]
Output:
[10, 5, 3, 6]
[5, 3, 6, 10]
[3, 6, 10, 5]
[6, 10, 5, 3]
[10, 3, 5, 6]
[3, 5, 6, 10]
[5, 6, 10, 3]
[6, 10, 3, 5]
[10, 5, 6, 3]
[5, 6, 3, 10]
[6, 3, 10, 5]
[3, 10, 5, 6]
[10, 6, 5, 3]
[6, 5, 3, 10]
[5, 3, 10, 6]
[3, 10, 6, 5]
[3, 6, 5, 10]
[6, 5, 10, 3]
[5, 10, 3, 6]
[10, 3, 6, 5]
[3, 10, 5, 6]
[10, 5, 6, 3]
[5, 6, 3, 10]
[6, 3, 10, 5]
....
This is not the end of the list, but I am looking for something that can output all combinations of array, given placement should be considered.
For now, I've comeout with something to switch the place
def rotateArray(arr, n, d):
temp = []
i = 0
while (i < d):
temp.append(arr[i])
i = i + 1
i = 0
while (d < n):
arr[i] = arr[d]
i = i + 1
d = d + 1
arr[:] = arr[: i] + temp
return arr
spam = [3, 10, 5, 6]
for i in range(0,len(spam)):
spam = [3, 10, 5, 6]
a = rotateArray(spam, len(spam), i)
print(a)
That will switch by 1 place of all value, but not random switching.

You can use a built-in function:
from itertools import permutations
arr = [10, 5, 3, 6]
print(list(permutations(arr)))

Related

Split list into sublists of length x (with or without overlap)

There are many similar questions on here, but I can't find exactly what I'm looking for.
I want to split a list into sublists, each of which is exactly length x. This can include overlap, and the area of overlap doesn't matter so much. For example:
list_to_split = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
max_len = 3
desired_result = [[1, 2, 3], [3, 4, 5], [6, 7, 8], [8, 9, 10]]
# or
max_length = 4
desired_result = [[1, 2, 3, 4], [4, 5, 6, 7], [7, 8, 9, 10]]
# or
max_len = 5
desired_result = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
It doesn't matter how many final sublists there are, though I don't want any more than necessary.
It also doesn't matter where the overlap happens, I just need to capture all the individual items in the original list and have each sublist result in the same number of items.
Thanks!
You can adjust the accepted answer by NedBatchelder in this thread to work for the described scenario.
This is a generator function which I think is a pretty neat solution.
def chunks(lst, n):
"""Yield successive n-sized chunks from lst."""
# n must not be 0
for i in range(0, len(lst), n):
if i + n >= len(lst):
yield lst[-n:]
else:
yield lst[i:i + n]
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for i in range(1, 11):
print(list(chunks(l, i)))
Expected output:
[[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], [8, 9, 10]]
[[1, 2, 3, 4], [5, 6, 7, 8], [7, 8, 9, 10]]
[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
[[1, 2, 3, 4, 5, 6], [5, 6, 7, 8, 9, 10]]
[[1, 2, 3, 4, 5, 6, 7], [4, 5, 6, 7, 8, 9, 10]]
[[1, 2, 3, 4, 5, 6, 7, 8], [3, 4, 5, 6, 7, 8, 9, 10]]
[[1, 2, 3, 4, 5, 6, 7, 8, 9], [2, 3, 4, 5, 6, 7, 8, 9, 10]]
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]
The trick as I see it is to iterate an index in steps of x but "clip" the last one to be no less than x from the end:
>>> a = list(range(1, 11))
>>> x = 3
>>> [a[i:i+x] for i in (min(i, len(a) - x) for i in range(0, len(a), x))]
[[1, 2, 3], [4, 5, 6], [7, 8, 9], [8, 9, 10]]
Taken straight from itertools' recipes:
from itertools import zip_longest
def grouper(iterable, n, *, incomplete='fill', fillvalue=None):
"Collect data into non-overlapping fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, fillvalue='x') --> ABC DEF Gxx
# grouper('ABCDEFG', 3, incomplete='strict') --> ABC DEF ValueError
# grouper('ABCDEFG', 3, incomplete='ignore') --> ABC DEF
args = [iter(iterable)] * n
if incomplete == 'fill':
return zip_longest(*args, fillvalue=fillvalue)
if incomplete == 'strict':
return zip(*args, strict=True)
if incomplete == 'ignore':
return zip(*args)
else:
raise ValueError('Expected fill, strict, or ignore')
You may then use the "fill" option, and add the last item continuously if you wish to guarantee the size of the sublist:
>>> list_to_split = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> max_len = 3
>>> list(grouper(list_to_split, max_len, fillvalue=list_to_split[-1]))
[(1, 2, 3), (4, 5, 6), (7, 8, 9), (10, 10, 10)]
Iterate over the list, slicing max_len elements at a time. We start the slice at min(idx, len(list_to_split) - max_len)) in case we're too close to the end of the list:
list_to_split = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
max_len = 3
result = []
for idx in range(0, len(list_to_split), max_len):
start = min(idx, len(list_to_split) - max_len)
result.append(list_to_split[start:start + max_len])
print(result)
You can turn this into a list comprehension, but it's admittedly not very readable:
list_to_split = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
max_len = 3
result = [
list_to_split[
min(idx, len(list_to_split) - max_len):
min(idx, len(list_to_split) - max_len) + max_len]
for idx in range(0, len(list_to_split), max_len)
]
print(result)
Both of these output:
[[1, 2, 3], [4, 5, 6], [7, 8, 9], [8, 9, 10]]
Following code should do without any libraries, though there are many libraries too that you can use
def main():
'''The Main'''
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
x = 3
print([l[i:i+x] for i in range(0, len(l), x)])
if __name__ == '__main__':
main()
Output
[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]

How do I find the maximum value in an array within a dataframe column?

I have a dataframe (df) that looks like this:
a b
loc.1 [1, 2, 3, 4, 7, 5, 6]
loc.2 [3, 4, 3, 7, 7, 8, 6]
loc.3 [1, 4, 3, 1, 7, 8, 6]
...
I want to find the maximum of the array in column b and append this to the original data frame. My thought was something like this:
for line in df:
split = map(float,b.split(','))
count_max = max(split)
print count
Ideal output should be:
a b max_val
loc.1 [1, 2, 3, 4, 7, 5, 6] 7
loc.2 [3, 4, 3, 7, 7, 8, 6] 8
loc.3 [1, 4, 3, 1, 7, 8, 6] 8
...
But this does not work, as I cannot use b.split as it is not defined...
If working with lists without NaNs best is use max in list comprehension or map:
a['max'] = [max(x) for x in a['b']]
a['max'] = list(map(max, a['b']))
Pure pandas solution:
a['max'] = pd.DataFrame(a['b'].values.tolist()).max(axis=1)
Sample:
array = {'loc.1': np.array([ 1,2,3,4,7,5,6]),
'loc.2': np.array([ 3,4,3,7,7,8,6]),
'loc.3': np.array([ 1,4,3,1,7,8,6])}
L = [(k, v) for k, v in array.items()]
a = pd.DataFrame(L, columns=['a','b']).set_index('a')
a['max'] = [max(x) for x in a['b']]
print (a)
b max
a
loc.1 [1, 2, 3, 4, 7, 5, 6] 7
loc.2 [3, 4, 3, 7, 7, 8, 6] 8
loc.3 [1, 4, 3, 1, 7, 8, 6] 8
EDIT:
You can also get max in list comprehension:
L = [(k, v, max(v)) for k, v in array.items()]
a = pd.DataFrame(L, columns=['a','b', 'max']).set_index('a')
print (a)
b max
a
loc.1 [1, 2, 3, 4, 7, 5, 6] 7
loc.2 [3, 4, 3, 7, 7, 8, 6] 8
loc.3 [1, 4, 3, 1, 7, 8, 6] 8
Try this:
df["max_val"] = df["b"].apply(lambda x:max(x))
You can use numpy arrays for a vectorised calculation:
df = pd.DataFrame({'a': ['loc.1', 'loc.2', 'loc.3'],
'b': [[1, 2, 3, 4, 7, 5, 6],
[3, 4, 3, 7, 7, 8, 6],
[1, 4, 3, 1, 7, 8, 6]]})
df['maxval'] = np.array(df['b'].values.tolist()).max(axis=1)
print(df)
# a b maxval
# 0 loc.1 [1, 2, 3, 4, 7, 5, 6] 7
# 1 loc.2 [3, 4, 3, 7, 7, 8, 6] 8
# 2 loc.3 [1, 4, 3, 1, 7, 8, 6] 8

Replacing items in a list in all possible permutations

Let's say I have a list or an array of the type:
mylist = [1, 2, 3, 4]
And I want to replace an item in this list. Normally I would use something like the following:
mylist[2] = 7
That works well. However, can someone explain how to create all possible permutations of mylist when replacing one or more items in mylist. For example, I want to create the following:
[7, 2, 3, 4]
[7, 7, 3, 4]
[7, 2, 7, 4]
[7, 7, 7, 4]
[7, 2, 3, 7]
...(and so on)
I know I can use itertools to generate all possible permutations, but how can I specify that I want to substitute an item in all possible locations in the list before generating the permutations? Here is how I tried to use itertools:
list(itertools.permutations([1,2,3,4,7], 4))
This doesn't work because it doesn't substitute 7 more than one time per permutation, and it also generates permutations that do not include the number 7.
Use itertools.combinations to find the indices to replace:
replace = 7
mylist = [1, 2, 3, 4]
for i in range(1, len(mylist) + 1):
for selected in itertools.combinations(range(len(mylist)), i):
res = mylist[:]
for n in selected:
res[n] = replace
print(res)
Output:
[7, 2, 3, 4]
[1, 7, 3, 4]
[1, 2, 7, 4]
[1, 2, 3, 7]
[7, 7, 3, 4]
[7, 2, 7, 4]
[7, 2, 3, 7]
[1, 7, 7, 4]
[1, 7, 3, 7]
[1, 2, 7, 7]
[7, 7, 7, 4]
[7, 7, 3, 7]
[7, 2, 7, 7]
[1, 7, 7, 7]
[7, 7, 7, 7]
You can create a function and just pass the list and value to that function and you get what you want :
import itertools
def replaced_it(list_1,value):
final_list = []
len_=len(list_1)
track_index = [k for k, j in enumerate(list_1)]
for i in range(len(track_index) + 1):
empty_list = [value]
replaced_one = list_1[:]
for ia in itertools.permutations(track_index, r=i):
if ia:
for i, j in zip(ia, empty_list * len(ia)):
replaced_one[i] = j
if replaced_one not in final_list:
final_list.append(replaced_one)
replaced_one = list_1[:]
return final_list
print(replaced_it([1,2,3,4],7))
output:
[[7, 2, 3, 4], [1, 7, 3, 4], [1, 2, 7, 4], [1, 2, 3, 7], [7, 7, 3, 4], [7, 2, 7, 4], [7, 2, 3, 7], [1, 7, 7, 4], [1, 7, 3, 7], [1, 2, 7, 7], [7, 7, 7, 4], [7, 7, 3, 7], [7, 2, 7, 7], [1, 7, 7, 7], [7, 7, 7, 7]]

Merge 3 lists into 1 list [duplicate]

This question already has answers here:
How do I make a flat list out of a list of lists?
(34 answers)
Closed 6 months ago.
I want to merge 3 lists in to a single list.
For example, I have three lists:
a = [0, 3, 6, 9]
b = [1, 4, 7, 10]
c = [2, 5, 8, 11]
and finally I want to get
merged = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
out of a, b, c
Are there any faster way to merge these 3 lists?
Here's my code:
merged = []
a = [0, 3, 6, 9]
b = [1, 4, 7, 10]
c = [2, 5, 8, 11]
for i in range(0, len(a)):
merged.append(a[i])
merged.append(b[i])
merged.append(c[i])
import itertools as it
list(it.chain.from_iterable(it.izip(a,b,c)))
a = [0, 3, 6, 9]
b = [1, 4, 7, 10]
c = [2, 5, 8, 11]
d=[]
print [j for i in zip(a,b,c) for j in i]
Output:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
Using reduce is another option:
>>> a = [0, 3, 6, 9]
b = [1, 4, 7, 10]
c = [2, 5, 8, 11]
>>> reduce(lambda x, y: list(x)+list(y), zip(a,b, c))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
You can do it like this:
a = [0, 3, 6, 9]
b = [1, 4, 7, 10]
c = [2, 5, 8, 11]
merged=a+b+c
merged.sort()
Since you are adding the list the merged list will contains all values from abc but not in the correct order.That's why I used .sort() to sort the list

Better way to get sublist in python

I am working on the following problem:
This function returns a list of all possible sublists in L of length n without skipping elements in L. The sublists in the returned list should be ordered in the way they appear in L, with those sublists starting from a smaller index being at the front of the list.
Example 1, if L = [10, 4, 6, 8, 3, 4, 5, 7, 7, 2] and n = 4 then your function should return the list [[10, 4, 6, 8], [4, 6, 8, 3], [6, 8, 3, 4], [8, 3, 4, 5], [3, 4, 5, 7], [4, 5, 7, 7], [5, 7, 7, 2]]
My solution works but how can I make it shorter? What is a better way to do this?
def getSublists(L, n):
newN = n
myList = []
for i in range(len(L)):
orginalLen = L[i:n]
if(len(orginalLen) == n):
myList.append(L[i:n])
n = n + 1
else:
myList.append(L[i:n])
n = n + 1
if(newN == 1):
print(myList)
else:
print(myList[:len(myList)-(n-1)])
getSublists([10, 4, 6, 8, 3, 4, 5, 7, 7, 2],4)
getSublists([1], 1)
getSublists([0, 0, 0, 0, 0], 2)
OUTPUT
[[10, 4, 6, 8], [4, 6, 8, 3], [6, 8, 3, 4], [8, 3, 4, 5], [3, 4, 5, 7], [4, 5, 7, 7], [5, 7, 7, 2]]
[[1]]
[[0, 0], [0, 0], [0, 0], [0, 0]]
l = [1,2,3,4,5,6,87,9]
n = ..
print [l[i:i+n] for i in range(len(l)-n+1)]
maybe you need.
In one line:
get_sublists = lambda ls, n: [ls[x:x+n] for x in range(len(ls)-n+1)]
get_sublists([10, 4, 6, 8, 3, 4, 5, 7, 7, 2], 4)
[[10, 4, 6, 8], [4, 6, 8, 3], [6, 8, 3, 4], [8, 3, 4, 5], [3, 4, 5, 7], [4, 5, 7, 7], [5, 7, 7, 2]]
def get_sublists(L, n):
return [ L[i:i+n] for i in range(len(L)-n) ]
I completed the program a little better understanding of the reader.
def getSublists(L, n):
new_list = []
for i in range(len(L)-n+1):
a = L[i:i+n]
new_list.append(a)
return new_list
answer:
[[10, 4, 6, 8],
[4, 6, 8, 3],
[6, 8, 3, 4],
[8, 3, 4, 5],
[3, 4, 5, 7],
[4, 5, 7, 7],
[5, 7, 7, 2]]
This is pretty readable I think, to understand the concept. The idea here is to iterate through the numbers from 0 to the length of L, minus 4. And just take the sublist of L from your current index i, to i+4. Iterating to length-4 ensures you don't try to access an index out of bounds!
>>> for i in range(len(L)-4+1):
print L[i:i+4]
[10, 4, 6, 8]
[4, 6, 8, 3]
[6, 8, 3, 4]
[8, 3, 4, 5]
[3, 4, 5, 7]
[4, 5, 7, 7]
[5, 7, 7, 2]

Categories

Resources