sum of items in a 2d list - list

Im trying ti implement a function evenrow() that takes a two dimensional list of integers and returns True if each row of the table sums up to an even number and False otherwise (i.e.., if some row sums up to an odd number)
usage
>>> evenrow([[1, 3], [2, 4], [0, 6]])
True
>>> evenrow([[1, 3], [3, 4], [0, 5]])
False
This is what I got so far:
def evenrow(lst):
for i in range(len(lst)-1):
if sum(lst[i])%2==0: # here is the problem, it only iterates over the first item in the lst [1, 3] - i cant figure this out - range problem?
return True
else:
False
How do I get the loop to iterate over every item [1, 3], [2, 4], [0, 6] in the list and not just the first?
well I have gotten this far now:
def evenrow(lst):
for i in range(len(lst)-1):
if sum(lst[i]) %2 >0:
return False
else:
return True
and i get the following answer when executing different lists:
>>> evenrow([[1, 3], [2, 4], [0, 6]])
True
>>> evenrow([[1, 3], [3, 4], [0, 5]])
False
>>> evenrow([[1, 3, 2], [3, 4, 7], [0, 6, 2]])
True
>>> evenrow([[1, 3, 2], [3, 4, 7], [0, 5, 2]])
True
(the last one is not correct though - should be False) I just dont get why this is not working...

You are returning too early. You should check for all the pairs, only returning True afterwards, or return False if a odd sum is encountered.
Spoiler alert:
def evenrow(lst):
for i in range(len(lst)-1):
if sum(lst[i]) % 2 != 0: # here is the problem, it only iterates over the first item in the lst [1, 3] - i cant figure this out - range problem?
return False
return True
This will achieve the goal.

Related

How to update numpy column where column condition met?

If I have the following:
import numpy as np
a = np.array([[0, 1],
[1, 3],
[4, 4]])
And want to update the column value if a column condition is met. For example if the 2nd column value is greater than 2, then replace only that column value with 9.
a = [[0, 1],
[1, 9],
[4, 9]]
I would have thought this would work, but it updates all the values in that row.
a[a[:,1] > 2] = 9
But it replaces all the values in the row.
a =[[0, 1],
[9, 9],
[9, 9]]
I'm guessing I'm missing some understanding of how the boolean indexing is being created here.
You need:
import numpy as np
a = np.array([[0, 1],
[1, 3],
[4, 4]])
a[:,1]= np.where(a[:,1]>2, 9, a[:,1])
print(a)
Output:
array([[0, 1],
[1, 9],
[4, 9]])
why your code not working
try printing out print(a[a[:,1] > 2])
it will give output as:
[[1 3]
[4 4]]
It will check for 2nd index if it is greater than 2 it will return an entire row.

Zipp lists in python by iterating through a list of lists

I have two lists of lists as follows. To merge them, I usually do the following:
>>>from itertools import imap, ilist
>>>a = [1,2,3]
>>>b = [4,5,6]
>>> c = list(imap(list,izip(a,b)))
>>> c
[[1, 4]], [2, 5], [3, 6]]
However, now I have a list of list as follows:
[[1,2,3],
[4,5,6],
[7,8,9],
]
How do I iterate through each list and pass it to the izip function to obtain the following output:
[[1,4,7],[2,5,8],[3,6,9]]
Answer for edited Question:
>>> input_list=[[1,2,3],
[4,5,6],
[7,8,9],
]
Using map and zip:
>>> map(list,zip(*input_list))
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Using imap and izip:
>>> list(imap(list,list(izip(*input_list))))
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Answer for previous question:
By using list comprehension and two for loops:
input_list =[[[1],[2],[3]],
[[4],[5],[6]],
[[7],[8],[9]],
]
out_list = [[] for i in range(len(input_list))]
for each_row in input_list:
for i in range(len(each_row)):
out_list[i].extend(each_row[i])
print out_list
Output:
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
I think u need something like this:
input_list =[[1,2,3],
[4,5,6],
[7,8,9],
]
result = []
for i in range(len(input_list)):
temp = []
for list in input_list:
temp.append(list[i])
result.append(temp)
print result
result will be:
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]

Project Euler Number 24

Python 2.7.9
Hello I'm experiencing some problems with how python is handling my permutations algorithm.
So I want my function to take the set_list=[1,2,3,4] and return all the permutations of that list.
This was my idea. Move from left to right, starting at the index values 0,1 of set_list, flip the value of set_list[index] with the value of set_list[index+1], with the understanding that when you reach an end point you flip set_list[0] with set_list[-1]. I thought this was gucci.
Solution
Forward
1234
2134
2314
2341
1342
3142
3412
3421
1423
4123
4213
4231
The idea then being to just to a reverse sort of the previous sub-lists to derive all the possible permutations.
Solution Reverse
4321
4312
4132
1432
2431
2413
2143
1243
3241
3214
3124
1324
My python notes
x = [1,2,3,4]
print(x)
j k k j
x[0],x[1] = x[1],x[0]
print(x)
x[1],x[2] = x[2],x[1]
print(x)
x[2],x[3] = x[3],x[2]
print(x)
x[3],x[0] = x[0],x[3]
print(x)
x[0],x[1] = x[1],x[0]
print(x)
x[1],x[2] = x[2],x[1]
print(x)
x[2],x[3] = x[3],x[2]
print(x)
x[3],x[0] = x[0],x[3]
print(x)
x[0],x[1] = x[1],x[0]
print(x)
x[1],x[2] = x[2],x[1]
print(x)
x[2],x[3] = x[3],x[2]
print(x)
x[3],x[0] = x[0],x[3]
print(x)
Code returns:
[1, 2, 3, 4]
[2, 1, 3, 4]
[2, 3, 1, 4]
[2, 3, 4, 1]
[1, 3, 4, 2]
[3, 1, 4, 2]
[3, 4, 1, 2]
[3, 4, 2, 1]
[1, 4, 2, 3]
[4, 1, 2, 3]
[4, 2, 1, 3]
[4, 2, 3, 1]
[1, 2, 3, 4]
So for a lot of reasons recursively using this function doesn't work (I have no idea why):
def set_return(__LIST__,j,k):
__LIST__[j],__LIST__[k]=__LIST__[k],__LIST__[j]
return(__LIST__)
So I decided to try and sudo-bullshit-hack a solution together, and have only successfully succeed in pulling my hair out.
Step 1)
Create lists containing values from vertical lists of j,k based on characteristics of list x shouldn't be that hard right?
x = [1,2,3,4]
set_0 = range(0,len(x))*(len(x)-1)
set_1 = set_0[1:len(set_0)]+[set_0[0]]
Code Returns:
>>> set_0
[0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3]
>>> set_1
[1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0]
>>>
Step 2)
def shift(__LIST__,a,b):
j = int(__LIST__[a])
k = int(__LIST__[b])
__LIST__[a] = k
__LIST__[b] = j
return(__LIST__)
Code Output:
>>>
[1, 2, 3, 4]
[2, 1, 3, 4]
[2, 3, 1, 4]
[2, 3, 4, 1]
[1, 3, 4, 2]
[3, 1, 4, 2]
[3, 4, 1, 2]
[3, 4, 2, 1]
[1, 4, 2, 3]
[4, 1, 2, 3]
[4, 2, 1, 3]
[4, 2, 3, 1]
[1, 2, 3, 4]
>>> set_0
[0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3]
>>> set_1
[1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0]
>>> shift([1, 2, 3, 4],0,1)
[2, 1, 3, 4]
>>> shift([2, 1, 3, 4],1,2)
[2, 3, 1, 4]
>>> shift([2, 3, 1, 4],2,3)
[2, 3, 4, 1]
>>> shift([2, 3, 4, 1],3,0)
[1, 3, 4, 2]
>>>
So then I use this:
chi = [1,2,3,4]
set_0 = range(0,len(chi))*(len(chi)-1)
set_1 = set_0[1:len(set_0)]+[set_0[0]]
to_return=[]
x = [1,2,3,4]
for i in range(len(set_0)):
insert=shift(x,set_0[i],set_1[i])
to_return.append(insert)
x = insert
And get:
[[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4]]
Are there easier ways...yes. Can I "protect" x or insert or hell maybe even both with list() ...face palm. Posting anyway. Enjoy.
The issue you are having at the end of your code is that all your insert values are references to the same list x, which gets modified in place by the shift function. You only see [1, 2, 3, 4] values in your to_return list because that's the final value of x. If you printed x while the loop was running you'd see the other permutations, but storing a reference in to_return doesn't preserve the value when x is modified later.
Compare with this:
x = [1, 2]
y = [x, x, x, x] # y contains several references to the list x
print(y) # prints [[1, 2], [1, 2], [1, 2], [1, 2]]
x[0] = 0 # modify x in place
print(y) # prints [[0, 2], [0, 2], [0, 2], [0, 2]], all the 1's are gone!
To fix this issue you can copy the list before appending it to to_return. The copy won't change when you modify x again later. (An alternative solution would be to change shift to return a new list without changing the old one, but I'll leave exploring that option up to you.) When you're storing a copy, you don't even need to care about shift's return value, you can just keep using x directly:
for i in range(len(set_0)):
shift(x,set_0[i],set_1[i]) # ignore the return value, which is another reference to x
to_return.append(x[:]) # append a copy of x
The slice x[:] is a compact way of copying the list. You could use list(x) if you wanted to be a bit more explicit (at the cost of a few extra characters). Either version would be easily understood as a copy by experienced Python programmers.
Before I finish this answer, I want to make a few additional suggestions which are somewhat unrelated to the issue you were asking about.
First off, your algorithm doesn't actually find all the permutations of the list you're giving it. For instance, [4, 3, 2, 1] never appears (nor indeed any permutation where 4 appears directly before 3). So even if the code I suggest above "works" in terms of doing what you want it to do, it may not be doing the right thing in a larger sense.
Second is a matter of style. Python lets you name your variables whatever you like, but it's a very bad idea to use some kinds of names. In several of your functions you're using the name __LIST__ which is a really bad name for an argument. For one thing, double-underscore names are reserved for the interpreter. In some future version, Python might store some special value in the name __LIST__ (overwriting whatever you're using it for). Or it might expect that name to hold some specific kind of value, and break in some way if you store something else in it. So don't use double underscores for arbitrary variables!
Even if we ignore the double underscores, __LIST__ is not a great name because it's really long and hard to type. While a name that's more explicit is often good (e.g. number_of_things may be better than n), you have to balance that with being easy enough to read and type. It's probably not wise to use list, since that's the name of the builtin type, but lst is a pretty common abbreviation of it.
When it comes to names, above all, be consistent. It doesn't really matter if you use a and b for throwaway variables, but it's much more confusing when you sometimes use those, and other times use j, and k (without any obvious distinction between their meanings).
def factorial(n):
c=1
for i in range(1,n+1):
c*=i
return(c)
def set_start(LIST):
to_return=[]
for i in range(len(LIST)):
insert=[]
for x in range(len(LIST)):
if LIST[i]!=LIST[x]:
insert.append(LIST[x])
to_return.append(insert)
return(to_return)
def set_builder(NESTED_LIST):
to_return=[]
for i in range(len(NESTED_LIST)):
to_return.append(set_start(NESTED_LIST[i]))
return(to_return)
def set_chain(NESTED_LIST):
to_return=[]
for i in range(len(NESTED_LIST)):
to_return+=NESTED_LIST[i]
return(to_return)
def set_expand(SET):
to_return=[]
for i in range(len(SET)):
to_return+=[SET[i]]*factorial(len(SET)-1)
return(to_return)
def set_rotation(SET):
set_0 = range(0,len(SET)-1,2)
set_1 = range(1,len(SET),2)
to_return=[]
for i in range(len(set_0)):
to_return+=[SET[set_1[i]],SET[set_0[i]]]
return(to_return)
def recursive_chain(SET):
sub_set_lengths=[]
for i in range(len(SET)):
sub_set_lengths.append(len(SET[i]))
sub_set_lengths = sorted(list(set(sub_set_lengths)),reverse=True)
to_return=[]
for i in range(len(sub_set_lengths)):
insert=[]
for x in range(len(SET)):
if sub_set_lengths[i]==len(SET[x]):
insert+=SET[x]
to_return.append(insert)
return(to_return)
def recursive_return(to_return):
to_return = [to_return]
initialize = set_start(to_return[-1])
while len(to_return[-1])!=2:
to_return+=initialize
to_chain = list(set_builder(list(initialize)))
to_pass = list(set_chain(list(to_chain)))
initialize = list(to_pass)
for i in range(len(to_return)):
if len(to_return[i])!=2:
to_return[i]=set_expand(to_return[i])
to_return = recursive_chain(to_return)
to_return+=[set_rotation(to_return[-1])]
return(to_return)
def PERMUTATIONS(SET):
to_return=[]
to_pop = recursive_return(SET)
while to_pop[-1]!=[]:
insert=[]
for i in range(len(SET)):
insert.append(to_pop[i][0])
to_return.append(insert)
for i in range(len(SET)):
to_pop[i].pop(0)
return(to_return)

Generating random lists in Python query

I want my program to take numbers from 1 to X and randomly distribute those numbers between X/2 numbers of lists Y times. I don't want a number to be repeated during one shuffle, also I don't want the lists to repeat at all. So if there is list [1,2] there shouldn't be another list containing 1 or 2 in same shuffle and there shouldn't be another [1,2] or [2,1] in the whole result.
This is what I came up with, however, it keeps on repeating numbers. Any adice?
import random
def Shuffler():
amount = int(raw_input("Numbers up to: "))
times = int(raw_input("Number of shuffles: "))
numberslist = range(1,amount+1)
twos = []
thisshuffle = []
final = []
while len(final) < (amount/2)*times:
twos = []
thisshuffle = []
while len(twos) < 2:
if len(numberslist)!=0:
randomnumber = random.choice(numberslist)
if (randomnumber in twos) or (randomnumber in thisshuffle):
numberslist.remove(randomnumber)
else:
twos.append(randomnumber)
thisshuffle.append(randomnumber)
numberslist.remove(randomnumber)
else:
numberslist = range(1,amount+1)
if (twos or list(reversed(twos))) not in final:
final.append(twos)
k=0
for i in range(times): #this shit prints shit
print "%s:" % (i+1), final[k:k+amount/2]
print
k = k + amount/2
Shuffler()
Shuffler()
As ccf pointed out, your requirements aren't trivial. A few more steps and you'd have a sudoku generator :)
I tried a few solutions but they either didn't produce random output or were rather inefficient. Ccf's solution is clearly well written but it seems to have the same problem; it produces ordered output (e.g. [1, 2], [1, 3], [1, 4], [1, 5], [1, 6]).
#cff - wouldn't it be better to use itertools.combinations rather than itertools.permutations to avoid generating repetitions?
Here's a "solution" that's quite similar to ccf's (doesn't produce random output either):
import itertools
def Shuffler():
amount = int(raw_input("Numbers up to: "))
times = int(raw_input("Number of shuffles: "))
rng = range(1, amount+1)
perms = list(itertools.combinations(rng, 2))
lst_single = []
lst_all = []
for p in perms:
if len(lst_all) >= times:
for i, lst in enumerate(lst_all):
print str(i+1) + ": ", lst
break
if len(lst_single) == amount/2:
lst_all.append(lst_single)
lst_single = []
elif p[0] < p[1]:
p = list(p)
lst_single.append(p)
Shuffler()
Output
Numbers up to: 6
Number of shuffles: 3
1: [[1, 2], [1, 3], [1, 4]]
2: [[1, 6], [2, 3], [2, 4]]
3: [[2, 6], [3, 4], [3, 5]]
And here's a slightly hackish solution that seems to produce the output you want but in an inefficient way. It relies on a set for filtering out unwanted combinations but still wastes resources producing them in the first place.
import random
def Shuffler():
amount = int(raw_input("Numbers up to: "))
times = int(raw_input("Number of shuffles: "))
rng = range(1, amount+1)
final = []
lst_len = amount/2
combos_unique = set()
while len(combos_unique) < lst_len*times:
combo_rand = random.sample(rng, 2)
if combo_rand[0] < combo_rand[1]:
combos_unique.add(tuple(combo_rand))
tmp = []
for combo in combos_unique:
tmp.append(list(combo))
if len(tmp) >= lst_len:
final.append(tmp)
tmp = []
for i, lst in enumerate(final):
print str(i+1) + ": ", lst
Shuffler()
Output
Numbers up to: 6
Number of shuffles: 3
1: [[2, 6], [4, 6], [5, 6]]
2: [[4, 5], [1, 3], [1, 6]]
3: [[3, 4], [2, 4], [3, 5]]
You don't want any repeated numbers in one shuffle, and any repeated list ... and so on. This is not an easy task. Plus another fact is that, the unique sets of numbers are fixed, which cannot be set too high. For example, if you set "Numbers up to:" 5, and "Number of shuffles: " 20, for sure you will get repeated numbers.
The issue with your code, I see, is in this if statement:
if (twos or list(reversed(twos))) not in final:
final.append(twos)
(twos or list(reversed(twos))) is logical OR, the result is twos, because twos is not empty. I suggest you change the if statement to:
if (twos not in final) and (list(reversed(twos)) not in final):
final.append(twos)
The following code (python 2.7x) uses permutations and shuffle to generate numbers list. Next, make the list unique (e.g., no [1,2] and [2,1] in same list). then, divide them into groups based on number of shuffles specified by the user. Press any letter, script will exit. Hope it helps:
from itertools import permutations
from random import shuffle
def Shuffler():
try:
amount = input("Numbers up to: ")
p = list(permutations(range(1, amount + 1), 2))
p_uniq = [list(x) for x in p if x[::-1] in p and x[0]<=x[1]]
shuf_max = len(p_uniq) /(amount / 2)
times = shuf_max + 1 # set a higher value to trigger prompt
while times > shuf_max:
shuffle(p_uniq) # shuffle the unique list in place
times = input("Number of shuffles (MAX %s): " % (shuf_max))
else:
for i, group in enumerate(list(zip(*[iter(p_uniq[: (amount /2) * times + 1])]* (amount/2)))):
print "%i: " % (i + 1), list(group)
Shuffler()
except:
print 'quitting...'
Shuffler()
Output:
Numbers up to: 10
Number of shuffles (MAX 9): 8
1: [[6, 7], [1, 9], [2, 5], [5, 9], [9, 10]]
2: [[1, 10], [3, 8], [4, 10], [8, 10], [1, 5]]
3: [[1, 4], [6, 8], [3, 6], [2, 4], [4, 7]]
4: [[2, 10], [5, 8], [3, 9], [1, 7], [4, 9]]
5: [[1, 2], [7, 9], [1, 3], [6, 9], [1, 6]]
6: [[2, 9], [4, 8], [3, 5], [8, 9], [7, 10]]
7: [[2, 7], [2, 3], [7, 8], [3, 7], [3, 10]]
8: [[3, 4], [2, 6], [5, 6], [5, 7], [4, 6]]
Numbers up to:

Define a function createSquareMat_sumpos(...) which receives one argument, dim, an integer number greater than

Define a function createSquareMat_sumpos(...) which receives one argument, dim, an integer number greater than 0, and it returns a list of lists which represents a matrix of dimension dim x dim, so that each element in the matrix has as content the sum of the column + the row position.
As an example, the following code fragment:
print (createSquareMat_sumpos(2))
should produce the output:
[[0, 1], [1, 2]]
def createSquareMat_sumpos(dim):
list=[[]]*dim
for i in range(len(list)):
list[i]=[i,(i+1)] #### not sure what to write here ####
return list
this works for
print (createSquareMat_sumpos(2)) and gives [[0, 1], [1, 2]]
but print (createSquareMat_sumpos(3)) I need it to give me [[0, 1, 2], [1, 2, 3], [2, 3, 4]]
instead of
[[0, 1], [1, 2], [2, 3]]