Related
im looking to solve the problem mentioned in the title without any specific functions that may or may not exist for this[]. Something along the lines of using mostly loops.
I tought about reversing each individual row using list.reverse() and then moving the rows around but im not sure how to implement it.
try this new realization and this will not change the original Matrix
Matrix = [[1,2,3],[4,5,6],[7,8,9]]
newMatrix = []
for line in range(len(Matrix)):
newMatrix.append(sorted(Matrix[line],reverse=True))
newMatrix.reverse()
print(newMatrix)
print(Matrix)
output:
[[9, 8, 7], [6, 5, 4], [3, 2, 1]]
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Try This
Matrix = [[1,2,3],[4,5,6],[7,8,9]]
newMatrix = []
for line in range(len(Matrix)):
Matrix[line].reverse()
newMatrix.append(Matrix[line])
newMatrix.reverse()
print(newMatrix)
output
[[9, 8, 7], [6, 5, 4], [3, 2, 1]]
I'm trying to figure out how to transpose a matrix with vectors that contain an unequal amount of elements.
I'm just learning to program and I'm currently working through the Python Tutorial and I'm stuck on an example listed in "Nested List Comprehensions" here: https://docs.python.org/3/tutorial/datastructures.html#nested-list-comprehensions.
Here is a very slight variation of example shown in the Python Tutorial:
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
[[row[i] for row in matrix] for i in range(3)]
I decided to create my own solution for the example because I wanted the code to be a bit more dynamic, which was this:
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
[[row[i] for row in matrix] for i in range(len(matrix))]
However, shortly after coming up with my solution I noticed there was a lot of ways it could still break and tried figuring out a solution that wouldn't break under any of the following scenarios:
# Scenario 1: Vectors of unequal length sizes.
matrix = [
[1, 2, 3, 4],
[5, 6, 7],
[8, 9, 10, 11]
# Scenario 2: len(vector) > len(matrix)
matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8]
]
# Scenario 3: len(vector) < len(matrix)
matrix = [
[1, 2],
[3, 4],
[5, 6],
[7, 8]
]
If anyone can come up with a solution using nested list comprehensions that would be able to handle all 3 of these scenarios, I would greatly appreciate your help.
disclaimer: all of this assumes your rows are all of the same length (as should be for a matrix).
just a minor tweak will do:
[[row[i] for row in matrix] for i in range(len(matrix[0]))]
the point is to have i in the range of the length of the rows of you matrix len(matrix[0]) (i am using the first row here as it always should exist).
a more elegant way is using zip:
list(zip(*matrix))
although you will get tuples as rows. if you need lists you can do:
[list(row) for row in zip(*matrix1)]
This works for both equal and unequal row lengths by collapsing the sparse rows to the left:
[[row[i] for row in matrix if i < len(row)] for i in range(max(len(r) for r in matrix))]
So scenario 1
matrix = [
[1, 2, 3, 4],
[5, 6, 7],
[8, 9, 10, 11]]
becomes
[[1, 5, 8],
[2, 6, 9],
[3, 7, 10],
[4, 11]]
I learned to create and manage nested lists by building a NxM matrix and filling it with random integers.
I've solved it via a simple one-liner and struggled to write a comprehensive solution.
I call the first solution as a cheating because I got this tip from this website, but didn't completely understand how it works. So, I've tried to write a more detailed piece of code on my own, which was difficult, and I'm not completely sure I got it right.
The original solution:
from random import randint
size_n = int(input("Number of lists N "))
size_m = int(input("Number of elements M "))
matrix = [[randint(1,9) for m in range(size_m)] for n in range(size_n)]
print(matrix)
I had a hard time to create a list of list with the correct levels of loops in loops. I end up with the temporary matrix, but I'm not sure it's good solution.
The final solution:
from random import randint
size_n = int(input("Number of lists N "))
size_m = int(input("Number of elements M "))
matrix = []
for n in range(size_n):
tmp = []
for m in range(size_m):
tmp.append(randint(1,9))
matrix.append(tmp)
print(matrix)
Can you help me to understand what is the correct solution for the task?
P.S. Is it normal for developer to look for another solution if the code just works but you think it might be prettier?
matrix = [[randint(1,9) for m in range(size_m)] for n in range(size_n)]
Let's say our size_n is 5, for an example. Then range(size_n) gives
[0, 1, 2, 3, 4]
E. g. a list of 5 consecutive integers starting with 0. If you do something for each element of the list, that creates another list of the same size, for example:
>>>[88 for n in range(size_n)]
[88, 88, 88, 88, 88]
You are, of course, not limited by simple numbers, you can create, basically, anything. For example, empty lists:
>>>[[] for n in range(size_n)]
[[], [], [], [], []]
Then, of course, the inner lists don't have to be empty, you can populate them with numbers:
>>>[[1, 2, 3] for n in range(size_n)]
[[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]
Or you can use another range expression inside:
>>> [[range(1, 4)] for n in range(5)]
[[[1, 2, 3]], [[1, 2, 3]], [[1, 2, 3]], [[1, 2, 3]], [[1, 2, 3]]]
And you can use list comprehension on those inner lists just the same way:
>>> [[randint(1, 9) for m in range(1, 4)] for n in range(5)]
[[8, 4, 3], [6, 7, 2], [6, 8, 2], [9, 6, 1], [9, 1, 2]]
You can go deeper and deeper until you're bored or out of memory:
>>> [[[randint(1, 9) for n in range(1, 5)] for n in range(1, 4)] for n in range(5)]
[[[2, 9, 6, 1], [6, 7, 4, 5], [5, 9, 1, 7]], [[5, 2, 9, 3], [1, 8, 9, 7], [8, 4, 4, 8]], [[4, 4, 7, 9], [7, 1, 4, 2], [7, 8, 7, 3]], [[4, 4, 9, 9], [8, 8, 9, 5], [6, 1, 3, 9]], [[5, 9, 3, 2], [7, 5, 4, 7], [7, 7, 4, 3]]]
Nested list comprehension is usually the right solution, they are easy to read once you get used to the notation. Nested loops are OK too.
There's nothing wrong with looking for better ways to re-write your working code (I'd say, rather, it's wrong not to look), unless you develop an unhealthy obsession with it.
For Python 3 range(5) actually doesn't give [0, 1, 2, 3, 4] directly, but for this task it's effectively the same thing.
Suppose I have this list:
newlis = [[3, 6, 4, 10], [1, 9, 2, 5], [0, 7, 8]]
I want to sort it in a way that each list is sorted. For instance:
newlis = [[3, 4, 6, 10], [1, 2, 5, 9], [0, 7, 8]]
I tried to write this code:
for i in range(len(newlis)):
if j in newlis[i] < newlis[i+1]:
newlis[i],newlis[i+1]=newlis[i+1],newlis[i]
print newlis
It's not working though. Can someone please help me out? Built in function are not allowed.
There are many things wrong here (among which is that this sounds like a homework question and we aren't supposed to respond to those) but I will give you some helpful advice:
You are comparing element J in list I to list I + 1.
You would want to compare element J in list I to element J + 1 in list I.
Also, you appear to be attempting to sort backwards. You will end up with large left and small right.
Also this is not a sorting algorithm. What happens when you have an array like
[3,6,4,10] => [6,4,10,3]
which is still not ordered, at all. Sorting algorithms are simple, but not that simple. I recommend looking them up.
In if j in newlis[i] < newlis[i+1]:, you are comparing sublists and not the elements of the sublists itself. You need two loops, one for iterating on newlis, and one for sorting the elements of each sublist of newlis.
A sample using Bubble Sort:
You can test it here:
>>> newlis = [[3, 6, 4, 10], [1, 9, 2, 5], [0, 7, 8]]
>>> for sublist in newlis:
... for i in range(len(sublist) - 1):
... if sublist[i] > sublist[i + 1]:
... sublist[i], sublist[i + 1] = sublist[i + 1], sublist[i]
>>> print(newlis)
[[3, 4, 6, 10], [1, 2, 5, 9], [0, 7, 8]]
Links about Bubble Sort:
http://www-ee.eng.hawaii.edu/~tep/EE160/Book/chap10/subsection2.1.2.2.html
http://www.go4expert.com/articles/bubble-sort-algorithm-absolute-beginners-t27883/
Let's say I have an array defined as
[
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
and I wanted to get a vertical slice, returning [2, 5, 8]. Is there any way to do this with slicing syntax in straight Python? When I try to look up multidimensional slicing, the only results I tend to see are all talking about numpy, and using the syntax discussed there gives errors in raw Python.
I don't know of a direct way to get a vertical slice and this is probably more expensive than the list comprehension answer but still
z = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
list(zip(*z)[1])
[2, 5, 8]
Or this may be slightly less expensive
from itertools import izip, islice
list(*islice(izip(*z), 1, 2))
[2, 5, 8]
Sure. You could generally use a for loop. Or simply you could code like:
>>> test = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
>>> [row[1] for row in test]
[2, 5, 8]
This piece of code will generate a new list for a vertical slice. If you really need a slice operation, the following code would be useful:
>>> [item for sublist in test for item in sublist][1::len(test[0])]
[2, 5, 8]