I want to check whether row 1 is equal to column one and row two is equal to column 2 and so on. If a matrix is equal to its transpose.
I tried to solve the problem using the following code, but the function is returning none. Can some one help me with this
x = [[1, 2, 3],
[2, 3, 4],
[3, 4, 1]]
def rows(matrix):
list = [val for val in matrix]
list1 = [i for i in zip(*matrix)]
if list == list1:
return True
else:
return False
rows(x)
zip returns tuples, not lists:
>>> [val for val in x]
[[1, 2, 3], [2, 3, 4], [3, 4, 1]]
>>> [i for i in zip(*x)]
[(1, 2, 3), (2, 3, 4), (3, 4, 1)]
And they don't compare equal to each other:
>>> [1,2,3] == (1,2,3)
False
Instead, you can simply return the results of the comparison after converting to lists:
>>> x == [list(i) for i in zip(*x)]
True
Use map to map the sublists to tuples and compare, mapping to tuple shoud also be more efficient than changing tuples to lists:
def rows(matrix):
return zip(*matrix) == map(tuple, matrix)
The zip function returns a list of tuples:
>>> x = [[1, 2, 3],
[2, 3, 4],
[3, 4, 1]]
>>> zip(*x)
[(1, 2, 3), (2, 3, 4), (3, 4, 1)]
>>> x == zip(*x)
False
A list isn't equal to a tuple, even if it has the same elements. A list of lists isn't equal to a list of tuples, even if the inner lists/tuples contain the same elements. You can do what you want easily, and you were close!
>>> x == [list(i) for i in zip(*x)]
True
You can understand what is wrong with your program by running this:
x = [[1, 2, 3],[2, 3, 4],[3, 4, 1]]
def rows(matrix):
list = [val for val in matrix]
list1 = [i for i in zip(*matrix)]
print list
print list1
if list == list1:
return True
else:
return False
print rows(x)
Here print list prints list of lists, while print list1 prints list of touples.
Since lists and touples are different, the program returns False.
Related
Beginner question: I am trying to iterate over the lists and return each item to send to another list. I can only get it to return the last item in each list- 4 & 'home'. What am I doing wrong?
def held():
alist = [1, 2, 3, 4]
blist = ['bob', 'is','not', 'home']
for event in range(0,3):
for item in alist:
ide = item
acc_id = int(ide)
for item in blist:
sev = item
sever = str(sev)
return acc_id, sever
held()
The return statement can only get executed once in a method. It will only return the last elements because, the program will at first loop through the list and then return the values (that will then equals the last value of the list while that was the las iteration executed).
If you want to return something like [1, "bob", 2, "is"...], you could do something like :
array1 = [1, 3, 5]
array2= [2, 4, 6]
array3 = []
for index in range(0, len(array1)):
array3.append(array1[index])
array3.append(array2[index])
print(array3)
# Expexted output : [1, 2, 3, 4, 5, 6]
As said in the comments by Timus, if you want [(1, "bob"), (2, "is")...] as output, you can do:
array1 = [1, 3, 5]
array2= [2, 4, 6]
array3 = list(zip(array1 , array2))
print(array3)
# Expected output : [(1, 2), (3, 4), (5, 6)]
I have a list l1 that looks like [1,2,1,0,1,1,0,3..]. I want to find, for each element the indexes of elements which have same value as the element.
For eg, for the first value in the list, 1, it should list out all indexes where 1 is present in the list and it should repeat same for every element in the list. I can wrote a function to do that iterating through the list but wanted to check if there is any predefined function.
I am getting the list from Pandas dataframe columns, it would be good know if series/dataframe library offer any such functions
You can use numpy.unique, which can return the inverse too. This can be used to reconstruct the indices using numpy.where:
In [49]: a = [1,2,1,0,1,1,0,3,8,10,6,7]
In [50]: uniq, inv = numpy.unique(a, return_inverse=True)
In [51]: r = [(uniq[i], numpy.where(inv == i)[0]) for i in range(uniq.size)]
In [52]: print(r)
[(0, array([3, 6])), (1, array([0, 2, 4, 5])), (2, array([1])), (3, array([7])), (6, array([10])), (7, array([11])), (8, array([8])), (10, array([9]))]
i tried brute force..may be u can optimize
here is python3 code
L = [1,2,1,0,1,1,0,3]
D = dict()
for i in range(len(L)):
n =[]
if L[i] not in D.keys():
for j in range(len(L)):
if L[i] == L[j]:
n.append(j)
D[L[i]] = n
for j in D.keys():
print(j,"->",D.get(j))
You could achieve this using a defaultdict.
from collection import defaultdict
input = [1,2,1,0,1,1,0,3]
#Dictionary to store our indices for each value
index_dict = defaultdict(list)
#Store index for each item
for i, item in enumerate(input):
index_dict[item].append(i)
If you want a list which contains the indices of elements which are the same as the corresponding element in your input list, you can just create a reference to the dictionary:
same_element_indices = [index_dict[x] for x in input]
This has the advantage of only referencing the one object for each identical element.
Output would be:
[[0, 2, 4, 5],
[1],
[0, 2, 4, 5],
[3, 6],
[0, 2, 4, 5],
[0, 2, 4, 5],
[3, 6],
[7]]
You can also try something like this:
import pandas as pd
df = pd.DataFrame({'A': [1,2,1,0,1,1,0,3]})
uni = df['A'].unique()
for i in uni:
lists = df[df['A'] == i].index.tolist()
print(i, '-->', lists)
Output:
1 --> [0, 2, 4, 5]
2 --> [1]
0 --> [3, 6]
3 --> [7]
I have a list which contain a tuple, within each tuple there's a list and a interger value
E.g.
Mylist = [([1,1,3], 3),([1,1,3], 30),([2,2,3], 15),([1,3,3], 2)]
I want this list to return this tuple ([1,3,3], 2)
since Mylist[i][1] = 2 that is the min in the list.
Now, the built-in function min() doesn't really do that.. it compares it on the basis of the actual list that is Mylist[i][0]
I can perform this only if the list contains two items:
But i have not figured how to do it in a list of.. say 10 items!
def min(a,x,b,y):
t = a
if x >= y:
t = b
return t
Mylist = [([1,1,3], 3),([1,1,3], 30),([2,2,3], 15),([1,3,3], 2)]
print min(Mylist,key=lambda x:x[1])
You can provide a key to min function using lambda.
Output:([1, 3, 3], 2)
If you store your list with the value first then you can just use min and sorted directly:
Mylist = [(3, [1,1,3]), (30, [1,1,3]), (15, [2,2,3]),(2, [1,3,3])]
min(Mylist)
Output: (2, [1, 3, 3])
my solution
myList = [([1, 1, 3], 3), ([1, 1, 3], 30), ([2, 2, 3], 15), ([1, 3, 3], 2)]
minValue = [i for i in myList if i[1] == min([x[1] for x in myList])]
return a list of items with the min value
[([1, 3, 3], 2)]
for example if you have a list like
myList = [([1, 1, 3], 3), ([1, 1, 3], 30), ([2, 2, 3], 15), ([1, 3, 3], 2), ([1, 1, 3], 2)]
Result will be
[([1, 3, 3], 2),([1, 1, 3], 2)]
I don't know if you need this but works :D
Just for interest's sake, here's a functional approach:
def get_min_tuple(l):
def get_index(lst, num, index=0):
if num in lst[index]:
return index
else:
return get_index(lst, num, index + 1)
def find_min(l, smallest=None, assigned=False):
if l == []:
return smallest
else:
if not assigned:
smallest = l[0][1]
assigned = True
else:
if l[0][1] < smallest:
smallest = l[0][1]
return find_min(l[1:], smallest, assigned)
return l[get_index(l, find_min(l))]
While the one-liner of supplying a key to the min function is of course more useful in a practical sense, I thought I'd share this for educational purposes.
Time Complexity = n
Mylist = [([1,1,3], 3),([1,1,3], 30),([2,2,3], 15),([1,3,3], 2)]
minv=MyList[0][1]
minv1=MyList[0][0]
for lst in MyList:
if(lst[1]<minv):
minv=lst[1]
minv1=lst[0]
print(tuple(minv1,minv))
I am trying to create a function that can do this.
>>> rearrange_list([1,2,3],[4,5,6])
[[1,4],[2,5],[3,6]]
So far what I have is
def rearrange_list(my_list):
i = 0
n = 0
new_list = []
for i in range(0, len(my_list[n])):
for n in range(0,len(my_list)):
new_list += [my_list[n][i]]
print(new_list)
n += 1
return new_list
but this code returns [1, 4, 2, 5, 3, 6], a single list instead of
a list of lists like I want it to and I can't seem to figure out how to make the
function output a list of lists based on the index of the list inside the list.
Use zip like so:
zip(list_a, list_b)
You can use zip and a list comprehension:
>>> def rearrange_lists(a, b):
... return [list(x) for x in zip(a, b)]
...
>>> rearrange_lists([1,2,3], [4,5,6])
[[1, 4], [2, 5], [3, 6]]
>>>
Note that the above function only handles two lists. If you want to handle any number of lists, you can use this:
>>> def rearrange_lists(*lsts):
... return [list(x) for x in zip(*lsts)]
...
>>> rearrange_lists([1,2,3], [4,5,6], [7,8,9])
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
>>>
Use zip() instead:
>>> zip([1,2,3], [4,5,6])
[(1, 4), (2, 5), (3, 6)]
or, for your specific varargs version:
>>> lsts = ([1,2,3], [4,5,6])
>>> zip(*lsts)
[(1, 4), (2, 5), (3, 6)]
or map the results to lists if tuples won't do:
map(list, zip([1,2,3], [4,5,6])) # Python 2
[list(t) for t in zip([1,2,3], [4,5,6])] # Python 2 and 3
As a replacement for your function:
def rearrange_list(*my_lists):
return [list(t) for t in zip(*my_lists)]
Say I have list1 = [1,2,3,4] and list2 = [5,6,7,8]. How would I compare the first element, 1, in list1 with the first element, 5, in list2? And 2 with 6, 3 with 7, and so on.
I'm trying to use a for loop for this, but I'm not sure how to do it. I understand that doing for x in list1 just checks an element x to all elements in list1, but I don't know how to do it when comparing two lists the way I described.
You can traverse both lists simultaneously using zip:
for (x, y) in zip(list1, list2): do_something
The 'zip' function gives you [(1,5), (2,6), (3,7), (4,8)], so in loop iteration N you get the Nth element of each list.
The default comparison operators compare lists in lexicographical order. So you can say things like:
>>> [1, 2, 3, 4] < [5, 6, 7, 8]
True
If instead you want to compute the elementwise comparison, you can use map and cmp (or any other operator:
>>> map(cmp, [1, 2, 3, 4], [5, 6, 7, 8])
[-1, -1, -1, -1]
If your result is going to be a new list, then you can use a list comprehension:
new_list = [ some_function(i, j) for i, j in zip(list1, list2) ]
Here's a real example of the above code:
>>> list1 = [1, 2, 3, 4]
>>> list2 = [1, 3, 4, 4]
>>> like_nums = [ i == j for i, j in zip(list1, list2) ]
>>> print like_nums
[True, False, False, True]
This will make a list of bools that show whether items of the same index in two lists are equal to each other.
Furthermore, if you use the zip function, there is a way to unzip the result when you are done operating on it. Here's how:
>>> list1 = [1, 2, 3, 4]
>>> list2 = [1, 3, 4, 4]
>>> new_list = zip(list1, list2) # zip
>>> print new_list
[(1, 1), (2, 3), (3, 4), (4, 4)]
>>> newlist1, newlist2 = zip(*new_list) # unzip
>>> print list(newlist1)
[1, 2, 3, 4]
>>> print list(newlist2)
[1, 3, 4, 5]
This could be useful if you need to modify the original lists, while also comparing the elements of the same index in some way.