Reputation: 1631
My regex is something like below
text = 'id 5 result pass
id 4 result fail
id 3 result fail
id 2 result fail
id 1 result pass'
for i in re.finditer('id (.+?) result (.+)', text):
id = i.group(1)
result = i.group(2)
print 'id'
print 'result'
The output is OK. But how do I reverse it to get the results in the other order where id will start from 1 with the pass or fail result
Upvotes: 5
Views: 3869
Reputation: 189
When using finditer to change text we want to discover the changes first, and then make the changes in reverse order. Something like this:
# Pass 1: Find all replacements without changing the text.
replacements = []
for mo in pattern.finditer(text):
# This may be arbitrarily complicated...
<< compute old, new text based on mo >>
replacements.append((old, new),)
# Pass 2: Safely make all replacements by making them in reverse order.
for old, new in reversed(replacements):
text = text.replace(old, new)
Upvotes: 1
Reputation: 7944
A good way is (which will be faster than using a lambda
in the sorted):
sorted(re.finditer(...,text),key=attrgetter('group'),reverse=True):
Or you could turn the iterator into a list and reverse it:
for i in reversed(list(re.finditer('id (.+?) result (.+)', text))):
Upvotes: 6
Reputation: 304137
You could sort by the value of the id
. This will also work ok if the records are originally in a random order.
for i in sorted(re.finditer('id (.+?) result (.+)', text), key=lambda m:int(m.group(1))):
In the example given, the sort has O(n) complexity, since timsort detects the input as a single "run"
Upvotes: 1
Reputation: 1741
Assign the finditer call to a list and reverse it.
matches = list(re.finditer(...))
matches.reverse()
for i in matches:
# etc.
Upvotes: 4