Get 2 number in one For loop - python

How do I get two numbers in a loop?
I tried to use the zip function.
matrix = [[0,1,1,2],[0,5,0,0],[2,0,3,3]]
print(len(matrix[0]))
print(range(len(matrix[0])))
for i, x in zip(range(len(matrix)), range(len(matrix[0]))):
print(x)
But instead of my output being 0,1,2,3, it only prints up to 2

Is this what you're looking for?
matrix = [[0,1,1,2],
[0,5,0,0],
[2,0,3,3]]
for i in matrix:
for i, x in enumerate(i):
print(i, x)

Your matrix has only 3 indexes, so its range will produce 0, 1, 2. zip will only zip objects up to the length of the shortest object. If you want to zip to the length of the longest then you should import zip_longest from the itertools module. It will then zip based on the longest list and produce None in place of the items in the shorter list.
from itertools import zip_longest
matrix = [[0,1,1,2],
[0,5,0,0],
[2,0,3,3]]
print(len(matrix[0]))
print(range(len(matrix[0])))
for i, x in zip_longest( range(len(matrix)) , range(len(matrix[0])) ):
print(i, x)
OUTPUT
3
range(0, 4)
0 0
1 1
2 2
None 3
However this seems very verbose and clunky, you might be better to state what your really trying to achieve as there may be a much cleaner way to do it.

I think you need range for your given list.....
I am improving #Martin Schere answer based on your doubt....
matrix = [[0,1,1,2],
[0,5,0,0],
[2,0,3,3]]
for i,x in enumerate(matrix):
print("range="+str(i))#0,1,2
print("list="+str(x))#prints your matrix
hope...it will help you...

Related

Multiply two list of different sizes element wise without using libraries in python

#create a simple list in python
#list comprehension
x = [i for i in range(100)]
print (x)
#using loops
squares = []
for x in range(10):
squares.append(x**2)
print (squares)
multiples = k*[z for z in x] for k in squares
So in the last line of code I am trying to multiply both the lists. the problem is the lists are not of the same side and k*[z for z in x] this part is also incorrect.
For problems with iteration, I suggest anyone to check Loop Like A Native by Ned Batchelder and Looping like a Pro by David Baumgold
Option 1
If you want to multiply them as far as the shortest list goes, zip is your friend:
multiples = [a * b for a, b in zip (x, squares)]
Option 2
If you want a matrix with the product, then you can do it like this
result = [
[a * b for a in x]
for b in squares
]
I don't quite understand what the desired output would be. As the function stands now, you would have a list of lists, where the first element has 100 elements, the second one 400, the third 900, and so on.
One thing that's strange: The expression [z for z in x] defines a list that is identical to x. So, you might just write k*x
If you want to multiply the elements of both lists, you would have to write [[k*z for z in x] for k in squares]. This would lead to a list of 10 lists of 100 elements (or a 10x100-matrix) containing the products of your lists.
If you want to have one list of length 100 in the end that holds some kind of products, you will have to think about how to proceed with the shorter list.
EDIT: Or if you want to multiply them as far as possible until you reach the end of the shorter list, FRANCOIS CYRIL's solution is an elegant way to do so.
You can loop on each array to multiply element by element at the same position in a result array:
i = 0
arrayRes = []
while i < min (len(array1),len(array2)):
arrayRes.append(array1[i]*array2[i])
i+=1
Or do you prefer to multiply them, matrix way?
x = 0
y = 0
arrayRes = []
while x < len(array1):
arrayRes.append([])
while y < len(array2):
arrayRes[x].append(array1[x]*array2[y])
y+=1
x+=1

How to go through all combinations of 3 lists?

I have three lists and want to call a function which takes 3 arguments with all possible combinations of values of that 3 lists.
And if a condition is met, print the 3 values of the combination.
What is the fastest and best way to do that?
Here are my three lists:
a = np.linspace(0.01,constants.pi/2,50)
b = np.arange(20,62,2)
c = np.arange(0.3,1.5,0.1)
And I want to call a function let's say testAllCombination(a[i],b[j],c[k]) in each iteration, and if a the value returned is > 0, print the 3 values a[i], b[j] and c[k]. Is it possible to do this in a simple way?
It seems you need the Cartesian product of your lists.
import itertools
list(itertools.product(a,b,c))
Note that this operation results in 50*21*12=12600 triples of items from a,b,c.
if the position is fixed to (a,b,c), you may consider simple loop. Otherwise if you need to change to other combinations like (b,c,a), (c,b,a)... use itertools
a = np.linspace(0.01,3.14/2,50)
b = np.arange(20,62,2)
c = np.arange(0.3,1.5,0.1)
myCombination=[]
for i in a:
for j in b:
for k in c:
myCombination.append((i,j,k))
print(myCombination)
for item in myCombination:
testCondition(item)
https://docs.python.org/2/library/itertools.html

How to create a list of all possible lists satisfying a certain condition?

I'm currently trying to do project Euler problem 18 (https://projecteuler.net/problem=18), using the 'brute force' method to check all possible paths. I've just been trying the smaller, 'model' triangle so far.
I was using list comprehension to create a list of lists where the inner lists would contain the indices for that line, for example:
lst = [[a,b,c,d] for a in [0] for b in [0,1] for c in [0,1,2] for d in
[0,1,2,3] if b == a or b == a + 1 if c == b or c == b + 1 if d == c or d ==
c + 1]
This gives me the list of lists I want, namely:
[[0,0,0,0],[0,0,0,1],[0,0,1,1],[0,0,1,2],[0,1,1,1],[0,1,1,2],[0,1,2,2],
[0,1,2,3]]
Note: the if conditions ensure that it only moves to adjacent numbers in the next row of the triangle, so that
lst[i][j] = lst[i][j-1] or lst[i][j] = lst[i][j]-1
After I got to this point, I intended that for each of the inner lists, I would take the numbers associated with those indices (so [0,0,0,0] would be 3,7,2,8) and sum over them, and this way get all of the possible sums, then take the maximum of those.
The problem is that if I were to scale this up to the big triangle I'd have fifteen 'for's and 'if's in my list comprehension. It seems like there must be an easier way! I'm pretty new to Python so hopefully there's some obvious feature I can make use of that I've missed so far!
What an interesting question! Here is a simple brute force approach, note the use of itertools to generate all the combinations, and then ruling out all the cases where successive row indices differ by more than one.
import itertools
import numpy as np
# Here is the input triangle
tri = np.array([[3],[7,4],[2,4,6],[8,5,9,3]])
indices = np.array([range(len(i)) for i in tri])
# Generate all the possible combinations
indexCombs = list(itertools.product(*indices))
# Generate the difference between indices in successive rows for each combination
diffCombs = [np.array(i[1:]) - np.array(i[:-1]) for i in indexCombs]
# The only combinations that are valid are when successive row indices differ by 1 or 0
validCombs = [indexCombs[i] for i in range(len(indexCombs)) if np.all(diffCombs[i]**2<=1)]
# Now get the actual values from the triangle for each row combination
valueCombs = [[tri[i][j[i]] for i in range(len(tri))] for j in validCombs]
# Find the sum for each combination
sums = np.sum(valueCombs, axis=1)
# Print the information pertaining to the largest sum
print 'Highest sum: {0}'.format(sums.max())
print 'Combination: {0}'.format(valueCombs[sums.argmax()])
print 'Row indices: {0}'.format(indexCombs[sums.argmax()])
The output is:
Highest sum: 23
Combination: [3, 7, 4, 9]
Row indices: (0, 0, 1, 0)
Unfortunately this is hugely intensive computationally, so it won't work with the large triangle - but there are definitely some concepts and tools that you could extend to try get it to work!

(Python) Checking the 3x3 in a Sudoku, are there better ways to do this?

My partner in a summative for HS gave me this algorithm, I was hoping somebody could tell me if there is a more eloquent way of coding this..
CB is current board position(global), its a list of lists.
for a in xrange(0, 3):
for b in xrange(0, 3):
for j in xrange(1, 4):
for k in xrange(1, 4):
boxsum += CB[3a + j][3b + k]
if not(boxsum == 45):
return False
boxsum = 0
First, the following code is not indented correctly:
if not(boxsum == 45):
return False
boxsum = 0
(with the current indentation it will always fail on the first time this code is executed)
Second, in the following line:
boxsum += CB[3a + j][3b + k]
you probably meant to do:
boxsum += CB[3*a + j][3*b + k]
And last, in order to check a 3x3 part of sudoku game it is not enough to check the sum - you should also check that every number between 1-9 is present (or in other words, that all the numbers are in the range 1-9 and there is no number that appears more than once).
There are dozens of "cleaner" ways to do so.
First of all, why not use numpy for matrices, where you are obviously working with a matrix? I am assuming your numeration (which is a bit odd, why you start numerating from "1"?)
import numpy as np
CB = np.array(CB)
def constraint3x3check(CB):
return np.all(np.sum( CB[3*a+1:3*a+3, 3*b+1:3*b+3)==45 for a in range(3) for b in range(3))
Given the sum of the box equals 45, that doesn't mean there are all 1-9 numbers present.
You could for example add your numbers to set and check if the length of the set is always 9.
Since the sum 45 does not mean the answer is correct, necessarily, a different way is needed. Personally, I would join the rows into a single list and compare them to the list (1,2,...9), e.g.
#assuming this is your format...
box = [[4,2,3],[1,5,9],[8,7,6]]
def valid_box(box):
check_list = []
for row in box:
check_list += row
return list(range(1,10)) == sorted(check_list)
Although the code creating the list could also be done with list comprehension (I have no idea which one is more efficient, processor-wise)
def valid_box2(box):
return list(range(1,10)) == sorted( [item for row in box for item in row ] )
Merge list code taken from Making a flat list out of list of lists in Python

Finding the sum of a nested list of ints

import math
lists = [1,[2,3],4]
total = 0
for i in range(len(lists)):
total += sum(i)
print(total)
I want it to print,
>>>10
But throws an error.
I would like it to get it to add all numbers, including the ones within the nested if.
In your program, for i in range(len(lists)) - evaluates to 3 as the lists object has 3 element. and in the loop total += sum(i) it would try to do a int + list operation, which results in an error. Hence you need to check for the type and then add the individual elements.
def list_sum(L):
total = 0
for i in L:
if isinstance(i, list):
total += list_sum(i)
else:
total += i
return total
This is #pavelanossov 's comment - does the same thing, in a more elegant way
sum(sum(i) if isinstance(i, list) else i for i in L)
You can use flatten function in the compiler.ast module to flatten the list. Then simply sum up all the elements.
>>> lists = [1,[2,3],4]
>>> from compiler.ast import flatten
>>> sum(flatten(lists))
10
EDIT: Only works with Python 2.x
numpy.hstack() function is used to stack the sequence of input arrays horizontally (i.e. column wise) to make a single array which is what we require in OP example
import numpy as np
list1 = [1,[2,3],4]
M = np.hstack(list1)
print(np.sum(M))
gives
10
[Program finished]

Categories

Resources