Text to a list python - list

i'm trying to read a sudoku and put it on a list,
i have something like this.
0,0,0,0,7,0,2,6,0
0,6,0,8,0,2,0,3,5
0,0,5,3,0,0,0,7,0
0,7,6,0,0,0,0,2,0
0,8,9,6,0,0,0,4,0
0,3,0,5,4,0,0,8,0
0,0,0,2,8,0,0,0,0
0,2,0,4,0,0,0,0,3
0,0,8,7,0,3,6,0,0
i need convert it on a list like this
board = [['0', '0', '0', '0', '7', '0', '2', '6', '0'], ['0', '6', '0', '8',
'0', '2', '0', '3', '5'], ['0', '0', '5', '3', '0', '0', '0', '7', '0'],
['0','7', '6', '0', '0', '0', '0', '2', '0'], ['0', '8', '9', '6', '0',
'0', '0','4', '0'], ['0', '3', '0', '5', '4', '0', '0', '8', '0'],
['0', '0', '0', '2','8', '0', '0', '0', '0'], ['0', '2', '0', '4', '0',
'0', '0', '0', '3'], ['0','0', '8', '7', '0', '3', '6', '0', '0']]
I'm using this code but have a problem
tablero = open('sd1.txt', 'r')
board = [line.split(',') for line in tablero.readlines()]
The result is:
board = [['0', '0', '0', '0', '7', '0', '2', '6', '0\n'], ['0', '6', '0',
'8', '0', '2', '0', '3', '5\n'], ['0', '0', '5', '3', '0', '0', '0', '7',
'0\n'], ['0', '7', '6', '0', '0', '0', '0', '2', '0\n'], ['0', '8', '9',
'6', '0', '0', '0', '4', '0\n'], ['0', '3', '0', '5', '4', '0', '0', '8',
'0\n'], ['0', '0', '0', '2', '8', '0', '0', '0', '0\n'], ['0', '2', '0',
'4', '0', '0', '0', '0', '3\n'], ['0', '0', '8', '7', '0', '3', '6', '0',
'0\n']]

Use .strip() to remove leading and trailing whitespace (including the trailing newline that is causing your trouble):
board = [line.strip().split(',') for line in tablero.readlines()]

in case you have the problem at the end of line, you can do a right strip as same Jez but only on the right part..basically..it does the same but only the right of the string .
board = [line.rstrip().split(',') for line in tablero.readlines()]

I guess you need to remove the '\n' by using line.strip('\n\r').
Or you could also use line[:-1].split(','), which also removes the last newline character.

Related

combining multiple regular expressions

I have a text file that contains the following lines
! R1 R(1,2) 1.0881
! R2 R(1,3) 1.0881
! R3 R(1,4) 1.0881
! R4 R(1,5) 1.0881
! A1 A(2,1,3) 109.4712
! A2 A(2,1,4) 109.4712
! A3 A(2,1,5) 109.4712
! A4 A(3,1,4) 109.4712
! A5 A(3,1,5) 109.4712
! A6 A(4,1,5) 109.4712
! D1 D(2,1,4,3) -120.0
! D2 D(2,1,5,3) 120.0
! D3 D(2,1,5,4) -120.0
! D4 D(3,1,5,4) 120.0
To match everything, I am using two different Regular expressions.
RE1 = !\s\w(\d)\s+R\((\d),(\d+)\)\s+(\d\.\d+
RE2 = !\s\w(\d)\s+\w\((\d)+,\d,\d\)?,?\d?\s?\)\s+\d?\-?\d\d\d?.\d?\d?\d?\d?
How do I go about combining these two REs so that the code checks for one of the REs. Based one some of posts on SO, I have tried using '|' to concatnate the two expressions but all my attempts have resulted in a typeerror Here is one of my attempts:
pattern = re.compile(re.compile(r'!\s\w(\d)\s+R\((\d),(\d+)\)\s+(\d\.\d+)') | re.compile(r'!\s\w(\d)\s+\w\((\d)+,\d,\d\)?,?\d?\s?\)\s+\d?\-?\d\d\d?.\d?\d?\d?\d?'))
This should get everything you need in a single regex
([A-Z])(\d+)\s+\1\((\d+(?:,\d+)*)\)\s+(-?\d+\.\d+)
https://regex101.com/r/bJdcSc/1
( [A-Z] ) # (1)
( \d+ ) # (2)
\s+ \1 \(
( # (3 start)
\d+
(?: , \d+ )*
) # (3 end)
\) \s+
( -? \d+ \. \d+ ) # (4)
Maybe,
!\s+[A-Z](\d)\s{2,}[A-Z]\((\d+),(\d+)?,?(\d+)?,?(\d+)?,?\)\s{2,}(-?\d+\.\d*)
might be close to what you like to write.
Demo
Test
import re
regex = r"!\s+[A-Z](\d)\s{2,}[A-Z]\((\d+),(\d+)?,?(\d+)?,?(\d+)?,?\)\s{2,}(-?\d+\.\d*)"
string = """
! R1 R(1,2) 1.0881
! R2 R(1,3) 1.0881
! R3 R(1,4) 1.0881
! R4 R(1,5) 1.0881
! A1 A(2,1,3) 109.4712
! A2 A(2,1,4) 109.4712
! A3 A(2,1,5) 109.4712
! A4 A(3,1,4) 109.4712
! A5 A(3,1,5) 109.4712
! A6 A(4,1,5) 109.4712
! D1 D(2,1,4,3) -120.0
! D2 D(2,1,5,3) 120.0
! D3 D(2,1,5,4) -120.0
! D4 D(3,1,5,4) 120.0
"""
print(re.findall(regex, string))
Output
[('1', '1', '2', '', '', '1.0881'), ('2', '1', '3', '', '', '1.0881'),
('3', '1', '4', '', '', '1.0881'), ('4', '1', '5', '', '', '1.0881'),
('1', '2', '1', '3', '', '109.4712'), ('2', '2', '1', '4', '',
'109.4712'), ('3', '2', '1', '5', '', '109.4712'), ('4', '3', '1',
'4', '', '109.4712'), ('5', '3', '1', '5', '', '109.4712'), ('6', '4',
'1', '5', '', '109.4712'), ('1', '2', '1', '4', '3', '-120.0'), ('2',
'2', '1', '5', '3', '120.0'), ('3', '2', '1', '5', '4', '-120.0'),
('4', '3', '1', '5', '4', '120.0')]
If you wish to simplify/modify/explore the expression, it's been explained on the top right panel of regex101.com. If you'd like, you can also watch in this link, how it would match against some sample inputs.
RegEx Circuit
jex.im visualizes regular expressions:

While loop inside While loop in python?

I am a beginner in python.
The second loop only run for once, the first time only, but when the turn comes to the first loop and when e = e+1 - python skips the second loop!
Why?
The print order only work for once.
items = [['.', '.', '.', '.', '.', '.'],
['.', 'O', 'O', '.', '.', '.'],
['O', 'O', 'O', 'O', '.', '.'],
['O', 'O', 'O', 'O', 'O', '.'],
['.', 'O', 'O', 'O', 'O', 'O'],
['O', 'O', 'O', 'O', 'O', '.'],
['O', 'O', 'O', 'O', '.', '.'],
['.', 'O', 'O', '.', '.', '.'],
['.', '.', '.', '.', '.', '.']]
i=0
e=0
while e < 6 :
while i < 9 : #python run this loop only once, and never come back when e=e+1
print items[i][e]
i=i+1
e=e+1
After the 'i' loop runs once, i will be set to 9 and will stay as 9 until you reset.
so you can try to set it to 0 after e = e+1.
A useful technique you can try is also printing the values of 'e' and 'i' to see where the loops gone wrong
items = [['.', '.', '.', '.', '.', '.'],
['.', 'O', 'O', '.', '.', '.'],
['O', 'O', 'O', 'O', '.', '.'],
['O', 'O', 'O', 'O', 'O', '.'],
['.', 'O', 'O', 'O', 'O', 'O'],
['O', 'O', 'O', 'O', 'O', '.'],
['O', 'O', 'O', 'O', '.', '.'],
['.', 'O', 'O', '.', '.', '.'],
['.', '.', '.', '.', '.', '.']]
i=0
e=0
while e <6 :
while i <9 :
print items[i][e]
print 'loop: i'+str(i)+'e'+str(e)
i=i+1
e=e+1
i=0

Why does the implementation of set() in Python involve randomization?

I already known when I convert list A to set, then to list again (called B), the order will be changed. But I'm quite confused why the order of the list B also changes every time the code is run.
This is my code:
if __name__ == '__main__':
my_list = ['1', '2', '3', '4', '5']
print(my_list)
print(list(set(my_list)))
And this is the result:
1st run:
['1', '2', '3', '4', '5']
['2', '3', '5', '1', '4']
2nd run:
['1', '2', '3', '4', '5']
['2', '4', '3', '5', '1']

assigning a value to a list within a list

I am having a problem trying to assing a single value to a list within a list
example:
create a list with 11 lists of 11 strings
board=[['.'](10+1)](10+1)
board
[['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.']]
assign value 'O' to the first string of the first list
board[0][0]='O'
I am getting to following output
board
[['O', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['O', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['O', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['O', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['O', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['O', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['O', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['O', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['O', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['O', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['O', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.']]
Instead I was expected to have this other output that i am not getting:
[['O', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.'], ['.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.']]
That's it. I expected to get string 'O' only for the first element of the first listv in board!
I don't understand why i am getting value 'O' to the first value in every single list when I only selected the first one.
Thank you for any comment to all!
In your code, this line:
>>> board = [['.']*(10+1)]*(10+1)
appears to create a 2D grid with independent rows of cells however it doesn't quite do that, and this is a common issue experienced with creating n-dimensional lists in Python.
What this code does is create one row and then the board is a list where each item in the list references the same row.
You can see that by using id():
>>> id(board[0])
4497981128
>>> id(board[1])
4497981128
>>> id(board[2])
4497981128
>>> id(board[0]) == id(board[1]) == id(board[2])
True
All three memory addresses are the same, so changing an element at index i in one, changes it in all of them.
What you want to do is generate each row separately:
>>> board = [['.']*(10+1) for _ in range(10+1)]
(The _ is a convention for a needed but unused variable.)
This way each row is a separate object in memory:
>>> id(board[0]) == id(board[1]) == id(board[2])
False
>>> id(board[0])
4497941384
>>> id(board[1])
4497989256
>>> id(board[2])
4497919688
You can try this:
board = [["." for i in range(11)] for b in range(11)]
board[0][0] = "O"
That will give you the single "O" at the 0th index of the first list.

Find if certain characters are present in a string

I have the following code and want to see if the string 'userFirstName' contains any of the characters in the char array. If the string does I want it to ask the user to reenter their first name and then check the new name for invalid characters and so on.
char invalidCharacter[] = { '!', '#', '#', '$', '%', '^', '&', '*', '(', ')', '~', '`',
';', ':', '+', '=', '-', '_', '*', '/', '.', '<', '>', '?', ',', '[', ']', '{', '}',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
cout << "Please enter your first name: " << endl;
cin >> userFirstName;`
Use string::find_first_of to do it.
Assuming that userFirstName is a string:
size_t pos = userFirstName.find_first_of(invalidChars, 0, sizeof(invalidChars));
if (pos != string::npos) {
// username contains an invalid character at index pos
}