Permutations Function - python

I am a beginner coder, and have been struggling with defining a function that would return all the permutations of a given array. My current code is:
def Permutations(array):
result = []
idx = 0
for element in array:
for number in range(len(array)):
if number != idx:
array[array.index(element)] = array[number]
result.append(array)
idx += 1
return result
For some reason, I get a value error when I run the code. What is the issue with the code, as it seems to be logical to me?
Thank you!

You can do something like this:
def Permutations(array):
result = []
for id1, el1 in enumerate(array):
a = [el1]
for id2, el2 in enumerate(array):
if id1 != id2:
a.append(el2)
result.append(a)
return result
In [1]: Permutations([1, 2, 3])
Out[1]: [[1, 2, 3], [2, 1, 3], [3, 1, 2]]
So what I changed here was:
use enumerate instead of keeping a variable to track index
keep separate list to construct a permutation then add it to the final set of permutations

Related

Python: Duplicates in list

Im trying to create a new list of unique values and remove said values from the original list so that what's left is duplicates. It appears my for loop is skipping over values.
array = [1,3,4,2,2,3,4]
def duplicates(array):
mylist = []
for item in array:
if item not in mylist:
mylist.append(item)
array.remove(item)
return mylist
results:
duplicates(array)
[1, 4, 2]
I think that using collections.Counter is more appropriate for this task:
array = [1, 3, 4, 2, 2, 3, 4]
from collections import Counter
def duplicates(array):
return [n for n, c in Counter(array).items() if c > 1]
print(duplicates(array))
Output:
[3, 4, 2]
The issue is with the array.remove(item), it is deleting the element at the index position visited. So, index number reduces by one and making the loop to skip reading the next value.
[1, 3, 4, 2, 2, 3, 4] -> before 1st iteration index 0 -> value =1
[3, 4, 2, 2, 3, 4] -> After 1st iteration 1 is removed, so index 0 -> value =3(loop not reading it as it already read index 0, so loop is reading index 1 -> value 4)
Correct code to display values without duplicates:
array = [1,3,4,2,2,3,4]
def duplicates(array):
mylist = []
for item in array:
if item not in mylist:
mylist.append(item)
#array.remove(item)
return mylist
res=duplicates(array)
print (res)
You are removing values from the list you are iterating through, so your loop is skipping values, try this
array = [1,3,4,2,2,3,4]
def duplicates(array):
mylist = []
for i, item in enumerate(array):
if item not in mylist:
mylist.append(item)
array[i] = None
array[:] = list(filter(
lambda x: x is not None,
array
))
return mylist
Though you should clarify what you want to do with array variable as it is currently unclear.
array = [1,3,4,2,2,3,4]
def duplicates(array):
mylist = []
for item in array:
if item not in mylist:
mylist.append(item)
array.remove(item)
else:
array.remove(item)
return mylist
just remove the item that you don't append
You do not need to use a loop, it is much clearer to use a list comprehension
dups = list(set([l for l in array if array.count(l) > 1]))
However, the answer provided by kuco 23 does this appropriately with a loop.
A bit unclear what result you expect. If you want to get all unique values while maintaining order of occurrence, the canonical way to achieve this would be to use a collections.OrderedDict:
from collections import OrderedDict
def duplicates(array):
return list(OrderedDict.fromkeys(array))
>>> duplicates(array)
[1, 3, 4, 2]
If you want get a list of only duplicates, i.e. values that occur more than once, you could use a collections.Counter:
from collections import Counter
def duplicates(array):
return [k for k, v in Counter(array).items() if v > 1]
>>> duplicates(array)
[3, 4, 2]

Create N arrays of length M where the sequence is increased by 1 on each array

Good morning,
Given two numbers (a,b), I should create 'a' different list of length 'b' where the sequence of each list is increased by one.
For example :
1,2 =>[[0,1]]
2,2 = > [[0,1], [1,2]]
I am trying to write the following function:
def increase_arrays(arrays, length):
result = [[i for i in range(length)] for i in range(arrays)]
return result
increase_arrays(2,3)
=> [[0, 1, 2], [0, 1, 2]]
I can't see how to modify my code so the second array is [1,2,3].
Could anyone help to resolve the issue?
You have famous duplicated index problem, you have 2 indexes i.
Below is the code that you need:
def increase_arrays(arrays, length):
result = [[i + j for i in range(length)] for j in range(arrays)]
return result
increase_arrays(2, 3) returns [[0, 1, 2], [1, 2, 3]]
I finally managed to solve it with:
def increase_arrays(arrays, length):
return [list(range(i,length+i)) for i in range(arrays)]
Here's a numpy solution, just for fun:
np.arange(arrays)[:,np.newaxis] + np.arange(length)[np.newaxis,:]

Group repeated elements of a list

I am trying to create a function that receives a list and return another list with the repeated elements.
For example for the input A = [2,2,1,1,3,2] (the list is not sorted) and the function would return result = [[1,1], [2,2,2]]. The result doesn't need to be sorted.
I already did it in Wolfram Mathematica but now I have to translate it to python3, Mathematica has some functions like Select, Map and Split that makes it very simple without using long loops with a lot of instructions.
result = [[x] * A.count(x) for x in set(A) if A.count(x) > 1]
Simple approach:
def grpBySameConsecutiveItem(l):
rv= []
last = None
for elem in l:
if last == None:
last = [elem]
continue
if elem == last[0]:
last.append(elem)
continue
if len(last) > 1:
rv.append(last)
last = [elem]
return rv
print grpBySameConsecutiveItem([1,2,1,1,1,2,2,3,4,4,4,4,5,4])
Output:
[[1, 1, 1], [2, 2], [4, 4, 4, 4]]
You can sort your output afterwards if you want to have it sorted or sort your inputlist , then you wouldnt get consecutive identical numbers any longer though.
See this https://stackoverflow.com/a/4174955/7505395 for how to sort lists of lists depending on an index (just use 0) as all your inner lists are identical.
You could also use itertools - it hast things like TakeWhile - that looks much smarter if used
This will ignore consecutive ones, and just collect them all:
def grpByValue(lis):
d = {}
for key in lis:
if key in d:
d[key] += 1
else:
d[key] = 1
print(d)
rv = []
for k in d:
if (d[k]<2):
continue
rv.append([])
for n in range(0,d[k]):
rv[-1].append(k)
return rv
data = [1,2,1,1,1,2,2,3,4,4,4,4,5,4]
print grpByValue(data)
Output:
[[1, 1, 1, 1], [2, 2, 2], [4, 4, 4, 4, 4]]
You could do this with a list comprehension:
A = [1,1,1,2,2,3,3,3]
B = []
[B.append([n]*A.count(n)) for n in A if B.count([n]*A.count(n)) == 0]
outputs [[1,1,1],[2,2],[3,3,3]]
Or more pythonically:
A = [1,2,2,3,4,1,1,2,2,2,3,3,4,4,4]
B = []
for n in A:
if B.count([n]*A.count(n)) == 0:
B.append([n]*A.count(n))
outputs [[1,1,1],[2,2,2,2,2],[3,3,3],[4,4,4,4]]
Works with sorted or unsorted list, if you need to sort the list before hand you can do for n in sorted(A)
This is a job for Counter(). Iterating over each element, x, and checking A.count(x) has a O(N^2) complexity. Counter() will count how many times each element exists in your iterable in one pass and then you can generate your result by iterating over that dictionary.
>>> from collections import Counter
>>> A = [2,2,1,1,3,2]
>>> counts = Counter(A)
>>> result = [[key] * value for key, value in counts.items() if value > 1]
>>> result
[[2, 2, 2], [[1, 1]]

How to get the index of specific item in python matrix

I am newbie to Python programming language. And I am looking for How to get the indexes (line and column ) of specific element in matrix.
In other I way I want to do the same as this source code using lists.
myList=[1,10,54,85]
myList.index(54)
Best Regards
Here's a simple function which returns the coordinates as a tuple (or None if no index is found). Note that this is for 2D matrices, and returns the first instance of the element in the matrix.
(Edit: see hiro protagonist's answer for an alternative Pythonic version)
def find(element, matrix):
for i in range(len(matrix)):
for j in range(len(matrix[i])):
if matrix[i][j] == element:
return (i, j)
Or, if you want to find all indexes rather than just the first:
def findall(element, matrix):
result = []
for i in range(len(matrix)):
for j in range(len(matrix[i])):
if matrix[i][j] == element:
result.append((i, j))
return result
You can use it like so:
A = [[5, 10],
[15, 20],
[25, 5]]
find(25, A) # Will return (2, 0)
find(50, A) # Will return None
findall(5, A) # Will return [(0, 0), (2, 1)]
findall(4, A) # Will return []
a (in my opinion) more pythonic version of FlipTack's algorithm:
def find(element, matrix):
for i, matrix_i in enumerate(matrix):
for j, value in enumerate(matrix_i):
if value == element:
return (i, j)
in python it is often more natural to iterate over elements of lists instead of just the indices; if indices are needed as well, enumerate helps. this is also more efficient.
note: just as list.index (without a second argument) this will only find the first occurrence.
Since you say that you're a beginner, pardon me if you already know some of the below. Just in case I'll describe the basic logic you can use to write your own function or understand the other answers posted here better:
To access an element in a specific row of a list, for example, if you wanted to get the first element and save it in a variable:
myList=[1,10,54,85]
myvar = myList[0] # note that you access the first element with index 0
myvar now stores 1. Why index 0? Think of the index as an indicator of "how far away from the beginning of the list an element is." In other words, the first element is a distance of 0 from the start.
What if you have a multi-dimensional list like so?
multi = [[0, 1, 2],
[3, 4, 5],
[6, 7, 8]
]
Now you think in terms of row and column (and of course you could have n-dimensional lists and keep going).
How to retrieve the 5? That is a distance of 1 row from the start of the list of rows and 2 columns away from the start of the sub-list.
Then:
myvar = multi[1][2]
retrieves the 5.
FlipTack's and hiro protagonist's functions wrap this logic in the nice compact procedures, which search the entire 2-dimensional list, comparing elements until the desired one is found, then returning a tuple of the indices or continuing to search for duplicate elements. Note that if your lists are guaranteed to sorted you can then use a binary search algorithm across rows and columns and get the answer faster, but no need to worry about that for now.
Hopefully this helps.
You can also add a tag to your function to search the occurrences of your input matrix/list.
For example:
If you input is 1D vector:
def get_index_1d(a = [], val = 0, occurrence_pos = False):
if not occurrence_pos:
for k in range(len(a)):
if a[k] == val:
return k
else:
return [k for k in range(len(a)) if a[k] == val]
Output:
a = [1,10,54,85, 10]
index = get_index_1d(a, 10, False)
print("Without occurrence: ", index)
index = get_index_1d(a, 10, True)
print("With occurrence: ", index)
>>> Without occurrence: 1
>>> With occurrence: [1, 4]
For 2D vector:
def get_index_2d(a = [], val = 0, occurrence_pos = False):
if not occurrence_pos:
for k in range(len(a)):
for j in range(len(a[k])):
if a[k][j] == val:
return (k, j)
else:
return [(k, j) for k in range(len(a)) for j in range(len(a[k])) if a[k][j] == val]
Output:
b = [[1,2],[3,4],[5,6], [3,7]]
index = get_index_2d(b, 3, False)
print("Without occurrence: ", index)
index = get_index_2d(b, 3, True)
print("With occurrence: ", index)
>>> Without occurrence: (1, 0)
>>> With occurrence: [(1, 0), (3, 0)]
Just wanted to throw another solution since I didn't see it above:
def find(matrix, value):
value_indexs = [ ( matrix.index(row), row.index(value) ) for row in matrix if value in row]
return value_indexs
Example:
matrix = [
[0, 1, 2],
[3, 4, 5, 6],
[7, 8, 9, 0]
]
find(matrix, 0)
Returns: [(0,0), (2,3)]

How to add column elements of a 2D list and return result in a list?

Write a function that takes a two-dimensional list (list of lists) of
numbers as argument and returns a list which includes the sum of each
column. Assume that the number of columns in each row is the same.
I know how to traverse a row in a multidimensional list but have been facing problem on how to traverse the column elements of a multidimensional list. I'm just a beginner with python. There's no logic I can come up with using for loop or any of the list manipulation methods. I haven't come across the advance topics of lambda or anything of that sort. Any help would be appreciated.
Transpose and sum each column:
In [1]: arr = [[1,2,3],
[4,5,6]]
In [2]: list(map(sum, zip(*arr)))
Out[2]: [5, 7, 9]
zip(*arr) gives you the columns:
In [3]: list(zip(*arr))
Out[3]: [(1, 4), (2, 5), (3, 6)]
Then mapping sum on each column gives you the sum for each.
If you prefer a list comp:
In [5]: [sum(col) for col in zip(*arr)]
Out[5]: [5, 7, 9]
def _sum_of_columns_sample_(sample_list):
cols = len(sample_list[0])
mylist = []
for c in range(cols):
column_sum = 0
for row in sample_list:
column_sum += row[c]
mylist.append(column_sum)
return mylist
That's not the most beautiful piece of code I've ever come up with, but it should do the trick. If you would use packages such as numpy, things get significantly easier.
a = [1,2,3]
b = [4,5,6]
res = []
for i in range(len(a)):
res.append(a[i] + b[i])
A 2 dimensional list can be expressed a list of lists. That is
>>> mylist = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]]
>>>len(mylist)
You can now create a sum using nested for loops. Note that this assumes that there are the same number of elements in each column.
mysum = [0, 0, 0, 0]
for i in range(len(mylist)):
for j in range(len(mylist[0])):
mysum[i] += mylist[i][j]
print mysum
If you want to make it more general (and allow for different sized columns) without having to create an explicit mysum list you can use the following code.
mysum = []
for i in range(len(mylist)):
total = 0
for j in range(len(mylist[i])):
total += mylist[i][j]
mysum.append(total)
print mysum

Categories