Select and compare every element in a column-list - python

I am trying to solve this puzzle question:
There is only one five-digit number n, such that every one of the following ten numbers share exactly one digit in common in the same position as n. Find n.
I'm trying to get like this:
https://i.stack.imgur.com/hufIc.jpg
For each column, selects every element and compares it along the column if it matches the same number. And then, appends it to get which number were matched on every column.
should i add if's in here:
L = [[0, 1, 2, 6, 5],
[1, 2, 1, 7, 1],
[2, 3, 2, 5, 7],
[3, 4, 5, 4, 8],
[4, 5, 9, 7, 0],
[5, 6, 2, 3, 6],
[6, 7, 3, 2, 4],
[7, 8, 0, 8, 4],
[8, 9, 8, 7, 2],
[9, 9, 4, 1, 4]]
for c in range(10):
for r in range(5):
print(L[c][r], end=' ')
print()

The easiest way I can think of is to get all the values of a column in a variable and then check if any value occurs more than once. The solution would look something like:
L = [
[0, 1, 2, 6, 5],
[1, 2, 1, 7, 1],
[2, 3, 2, 5, 7],
[3, 4, 5, 4, 8],
[4, 5, 9, 7, 0],
[5, 6, 2, 3, 6],
[6, 7, 3, 2, 4],
[7, 8, 0, 8, 4],
[8, 9, 8, 7, 2],
[9, 9, 4, 1, 4]
]
for r in range(5):
val = [L[c][r] for c in range(10)]
for i in range(10):
if val[i] in val[:i]:
print(val[i], end=" ")
break
else:
print(0, end=" ")
print()

L = [
[0, 1, 2, 6, 5],
[1, 2, 1, 7, 1],
[2, 3, 2, 5, 7],
[3, 4, 5, 4, 8],
[4, 5, 9, 7, 0],
[5, 6, 2, 3, 6],
[6, 7, 3, 2, 4],
[7, 8, 0, 8, 4],
[8, 9, 8, 7, 2],
[9, 9, 4, 1, 4]
]
for col_index in range(5):
col= [row[col_index] for row in L]
duplicate = [x for x in col if col.count(x) > 1]
if len(duplicate) == 0:
print(0, end=" ")
else:
print(duplicate[0], end=" ")
print()

Related

list.copy() not creating an true copy [duplicate]

This question already has answers here:
What is the difference between shallow copy, deepcopy and normal assignment operation?
(12 answers)
Closed 3 years ago.
I'm trying to write a little bit of code to complete an exercise on codewars link
Part of what I want to do is loop through a list of lists that are representing the sudoku grid and replace 0's with a list of possible numbers.
My problem is that even when I use list.copy() to hold the original puzzle any changes I make to the original list (not the copy) still changes the copy.
How can this be happening?
Below is my code:
def sudoku(puzzle):
# copy the puzzle to be able to save original positions that are changeable
pc = puzzle.copy()
puzzle = pns(puzzle)
return puzzle
def pns(puzzle):
for y in range(len(puzzle)):
for x in range(len(puzzle[0])):
pn = set(range(1,len(puzzle) + 1))
for row_idx in range(len(puzzle)):
for col_idx in range(len(puzzle[row_idx])):
skip_bool = True
if puzzle[y][x] != 0 and type(puzzle[y][x]) == type(1):
skip_bool = False
if row_idx == y and col_idx != x and type(puzzle[row_idx][col_idx]) != type([0]):
if puzzle[row_idx][col_idx] in pn:
pn.remove(puzzle[row_idx][col_idx])
if col_idx == x and row_idx != y and type(puzzle[row_idx][col_idx]) != type([0]):
if puzzle[row_idx][col_idx] in pn:
pn.remove(puzzle[row_idx][col_idx])
pn = list(pn)
if len(pn) == 1:
puzzle[y][x] = pn[0]
elif len(pn) == 0:
puzzle[y][x] = False
elif skip_bool:
puzzle[y][x] = pn
return puzzle
Expected output from:
print(pc)
print(puzzle)
[5, 3, 0, 0, 7, 0, 0, 0, 0]
[6, 0, 0, 1, 9, 5, 0, 0, 0]
[0, 9, 8, 0, 0, 0, 0, 6, 0]
[8, 0, 0, 0, 6, 0, 0, 0, 3]
[4, 0, 0, 8, 0, 3, 0, 0, 1]
[7, 0, 0, 0, 2, 0, 0, 0, 6]
[0, 6, 0, 0, 0, 0, 2, 8, 0]
[0, 0, 0, 4, 1, 9, 0, 0, 5]
[0, 0, 0, 0, 8, 0, 0, 7, 9]
[5, 3, [1, 2, 4, 6, 9], [2, 6, 9], 7, [1, 2, 4, 6, 8], [1, 4, 6, 8, 9], [1, 2, 4, 9], [2, 4, 8]]
[6, [2, 4, 7, 8], [2, 3, 4, 7], 1, 9, 5, [3, 4, 7, 8], [2, 3, 4], [2, 4, 7, 8]]
[[1, 2, 3], 9, 8, [2, 3, 5, 7], [3, 4, 5], [1, 2, 4, 7], [1, 3, 4, 5, 7], 6, [2, 4, 7]]
[8, [1, 2, 4, 5, 7], [1, 2, 4, 5, 7, 9], [2, 5, 7, 9], 6, [1, 2, 4, 7], [1, 4, 5, 7, 9], [1, 2, 4, 5, 9], 3]
[4, [2, 5, 7], [2, 5, 6, 7, 9], 8, 5, 3, [6, 7, 9], [2, 9], 1]
[7, [1, 4, 5, 8], [1, 3, 4, 5, 9], [3, 5, 9], 2, [1, 4, 8], [1, 3, 4, 5, 8, 9], [1, 3, 4, 5, 9], 6]
[[1, 3, 9], 6, [1, 3, 4, 5, 7, 9], [3, 5, 7, 9], [3, 4], [1, 4, 7], 2, 8, [4, 7]]
[[2, 3], [2, 7, 8], [2, 3, 6, 7], 4, 1, 9, [3, 6, 7, 8], [2, 3], 5]
[[1, 2, 3], [1, 2, 4, 5], [1, 2, 3, 4, 5, 6], [2, 3, 5, 6], 8, [1, 2, 4, 6], [1, 3, 4, 5, 6], 7, 9]
What I actually get back is 2 copies of the second list.
For nested structures, .copy() only will create a copy of the top-level objects, but the references contained within will still be the same references.
You probably want copy.deepcopy().

How to swap items in a list within a list python

I am trying to randomly swap 2 items in each list within a list, where those to be swapped are not in another list.
Here is my code
import random
def swap(mylist):
remain = [[1, 2], [4], [], [8, 2], [1, 4], [5, 2, 1], [], [9, 5], [7]]
for x in range(0, 9):
remaining = set(mylist[x]) - set(remain[x])
to_swap = random.sample(remaining, 2)
mylist[x][mylist[x].index(to_swap[0])], mylist[x][mylist[x].index(to_swap[1])] = mylist[x][mylist[x].index(to_swap[1])], mylist[x][mylist[x].index(to_swap[0])]
return mylist
print(swap([[8, 5, 4, 1, 3, 9, 7, 6, 2], [9, 3, 5, 6, 4, 7, 1, 2, 8], [7, 3, 2, 5, 4, 1, 9, 6, 8], [2, 1, 3, 8, 6, 9, 5, 7, 4], [1, 2, 3, 5, 7, 4, 9, 8, 6], [6, 9, 3, 1, 7, 4, 2, 8, 5], [1, 2, 7, 4, 3, 8, 5, 9, 6], [3, 7, 8, 4, 1, 5, 9, 6, 2], [4, 2, 6, 5, 7, 1, 9, 3, 8]]))
Whenever I run this and print out the result, it just prints out my input again.
Does anyone know what is wrong with my code?
Thanks.
Your code performs the swaps with about one half of the sublists. I wonder what the reason of this behavior is *(see below).
If you rewrite the swapping part like this:
i = mylist[x].index(to_swap[0])
j = mylist[x].index(to_swap[1])
mylist[x][i], mylist[x][j] = mylist[x][j], mylist[x][i]
then it works.
UPDATE:
There is no need to access the lists on the right-hand side of the assignment, since we already know the values, so the updated answer would be:
i = mylist[x].index(to_swap[0])
j = mylist[x].index(to_swap[1])
mylist[x][i], mylist[x][j] = to_swap[1], to_swap[0]
*UPDATE 2:
The above mentioned behavior is caused by the fact that in multiple assignments, expressions on the left-hand side are evaluated one by one from left to right. That means the OP's code didn't work in cases where index(to_swap[0]) < index(to_swap[1]).
Example: values 5 and 6 in the first sublist [8, 5, 4, 1, 3, 9, 7, 6, 2]. First, the program will do
mylist[x][mylist[x].index(5)] = 6
modifying the list to [8, 6, 4, 1, 3, 9, 7, 6, 2]. Second, the program will do
mylist[x][mylist[x].index(6)] = 5
modifying it back to [8, 5, 4, 1, 3, 9, 7, 6, 2].

Create a list of list with flexible input (Python) [duplicate]

This question already has answers here:
How can I make a for-loop pyramid more concise in Python? [duplicate]
(4 answers)
Closed 5 years ago.
I currently have a function that creates a list of lists like below using 3 nested for-loops.
[[1,1,1] , [1,1,2] , .... , [3,3,3]]
However, the problem is I can't use this function if someone wants the list of list to be something like
[[1,1,1,1,1,1,1] , ..... , [9,9,9,9,9,9,9]]
which has more numbers (from 1 - 9) and more elements (7 of 1's instead of 4).
Here's my current code:
def listofList():
temp = []
for i in range(1,4):
for j in range(1,4):
for k in range(1,4):
temp.append([i,j,k])
return temp
Can someone provide me with a better solution? I want my function listofList() to be flexible where it could receive an input for both the size of the list of list and the elements inside the list.
Try the following:
def listofList(subLen, totalLen):
final = [[item for i in range(subLen)] for item in range(1, totalLen+1)]
return final
>>> listofList(9, 9)
[[1, 1, 1, 1, 1, 1, 1, 1, 1], [2, 2, 2, 2, 2, 2, 2, 2, 2], [3, 3, 3, 3, 3, 3, 3, 3, 3], [4, 4, 4, 4, 4, 4, 4, 4, 4], [5, 5, 5, 5, 5, 5, 5, 5, 5], [6, 6, 6, 6, 6, 6, 6, 6, 6], [7, 7, 7, 7, 7, 7, 7, 7, 7], [8, 8, 8, 8, 8, 8, 8, 8, 8], [9, 9, 9, 9, 9, 9, 9, 9, 9]]
>>> listofList(9, 2)
[[1, 1, 1, 1, 1, 1, 1, 1, 1], [2, 2, 2, 2, 2, 2, 2, 2, 2]]
>>> listofList(2, 9)
[[1, 1], [2, 2], [3, 3], [4, 4], [5, 5], [6, 6], [7, 7], [8, 8], [9, 9]]
>>>

filtering a list of entries in python

I need to filter a list of character ie
In [16]: list
Out[16]: [[1, 2, 3, 4, 5, 6, 7, 8], [2, 3, 6, 3, 6, 2, 7], [4, 5, 9, 3, 1, 8]]
characters to grep is, g = [4,8]
In [27]: a = filter(lambda x:g in x, list)
In [28]: a
Out[28]: []
But I am ending up with this. Can someone help me?
I need the output as
[[1, 2, 3, 4, 5, 6, 7, 8], [4, 5, 9, 3, 1, 8]]
Your issue is that g in x is never True because g is a list that and that is never within one of your sub-lists, e.g. ([4,8] in [4,8,7] returns False). The right approach with filter:
l = [[1, 2, 3, 4, 5, 6, 7, 8], [2, 3, 6, 3, 6, 2, 7], [4, 5, 9, 3, 1, 8]]
g = [4,8]
filter(lambda x:all(c in x for c in g), l)
# [[1, 2, 3, 4, 5, 6, 7, 8], [4, 5, 9, 3, 1, 8]]
Or list comprehension:
[item for item in l if all(c in item for c in g)]
# [[1, 2, 3, 4, 5, 6, 7, 8], [4, 5, 9, 3, 1, 8]]
Note, don't name your variables list, this shadows the built-in name

Better way to get sublist in python

I am working on the following problem:
This function returns a list of all possible sublists in L of length n without skipping elements in L. The sublists in the returned list should be ordered in the way they appear in L, with those sublists starting from a smaller index being at the front of the list.
Example 1, if L = [10, 4, 6, 8, 3, 4, 5, 7, 7, 2] and n = 4 then your function should return the list [[10, 4, 6, 8], [4, 6, 8, 3], [6, 8, 3, 4], [8, 3, 4, 5], [3, 4, 5, 7], [4, 5, 7, 7], [5, 7, 7, 2]]
My solution works but how can I make it shorter? What is a better way to do this?
def getSublists(L, n):
newN = n
myList = []
for i in range(len(L)):
orginalLen = L[i:n]
if(len(orginalLen) == n):
myList.append(L[i:n])
n = n + 1
else:
myList.append(L[i:n])
n = n + 1
if(newN == 1):
print(myList)
else:
print(myList[:len(myList)-(n-1)])
getSublists([10, 4, 6, 8, 3, 4, 5, 7, 7, 2],4)
getSublists([1], 1)
getSublists([0, 0, 0, 0, 0], 2)
OUTPUT
[[10, 4, 6, 8], [4, 6, 8, 3], [6, 8, 3, 4], [8, 3, 4, 5], [3, 4, 5, 7], [4, 5, 7, 7], [5, 7, 7, 2]]
[[1]]
[[0, 0], [0, 0], [0, 0], [0, 0]]
l = [1,2,3,4,5,6,87,9]
n = ..
print [l[i:i+n] for i in range(len(l)-n+1)]
maybe you need.
In one line:
get_sublists = lambda ls, n: [ls[x:x+n] for x in range(len(ls)-n+1)]
get_sublists([10, 4, 6, 8, 3, 4, 5, 7, 7, 2], 4)
[[10, 4, 6, 8], [4, 6, 8, 3], [6, 8, 3, 4], [8, 3, 4, 5], [3, 4, 5, 7], [4, 5, 7, 7], [5, 7, 7, 2]]
def get_sublists(L, n):
return [ L[i:i+n] for i in range(len(L)-n) ]
I completed the program a little better understanding of the reader.
def getSublists(L, n):
new_list = []
for i in range(len(L)-n+1):
a = L[i:i+n]
new_list.append(a)
return new_list
answer:
[[10, 4, 6, 8],
[4, 6, 8, 3],
[6, 8, 3, 4],
[8, 3, 4, 5],
[3, 4, 5, 7],
[4, 5, 7, 7],
[5, 7, 7, 2]]
This is pretty readable I think, to understand the concept. The idea here is to iterate through the numbers from 0 to the length of L, minus 4. And just take the sublist of L from your current index i, to i+4. Iterating to length-4 ensures you don't try to access an index out of bounds!
>>> for i in range(len(L)-4+1):
print L[i:i+4]
[10, 4, 6, 8]
[4, 6, 8, 3]
[6, 8, 3, 4]
[8, 3, 4, 5]
[3, 4, 5, 7]
[4, 5, 7, 7]
[5, 7, 7, 2]

Categories

Resources