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:
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
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.