Reading \n unescaped from a file
Peter Otten
__peter__ at web.de
Sun Sep 6 03:51:01 EDT 2015
Friedrich Rentsch wrote:
> My response was meant for the list, but went to Peter by mistake. So I
> repeat it with some delay:
>
> On 09/03/2015 04:24 PM, Peter Otten wrote:
>> Friedrich Rentsch wrote:
>>
>>> On 09/03/2015 11:24 AM, Peter Otten wrote:
>>>> Friedrich Rentsch wrote:
>>> I appreciate your identifying two mistakes. I am curious to know what
>>> they are.
>> Sorry for not being explicit.
>>
>>>>> substitutes = [self.table [item] for item in hits if
>>>>> item
>>>>> in valid_hits] + [] # Make lengths equal for zip to work right
>>>> That looks wrong...
>> You are adding an empty list here. I wondered what you were trying to
>> achieve with that.
> Right you are! It doesn't do anything. I remember my idea was to pad the
> substitutes list by one, because the list of intervening text segments
> is longer by one element and zip uses the least common length,
> discarding all overhang. The remedy was totally ineffective and, what's
> more, not needed, judging by the way the editor performs as expected.
That's because you are getting the same effect later by adding
nohits[-1]
You could avoid that by replacing [] with [""].
>>> substitutes = list("12")
>>> nohits = list("abc")
>>> zipped = zip(nohits, substitutes)
>>> "".join(list(reduce(lambda a, b: a+b, [zipped][0]))) + nohits[-1]
'a1b2c'
>>> zipped = zip(nohits, substitutes + [""])
>>> "".join(list(reduce(lambda a, b: a+b, [zipped][0])))
'a1b2c'
By the way, even those who are into functional programming might find
>>> "".join(map("".join, zipped))
'a1b2c'
more readable.
But there's a more general change that I suggest: instead of processing the
string twice, first to search for matches, then for the surrounding text you
could achieve the same in one pass with a cool feature of the re.sub()
method -- it accepts a function:
>>> def replace(text, replacements):
... table = dict(replacements)
... def substitute(match):
... return table[match.group()]
... regex = "|".join(re.escape(find) for find, replace in replacements)
... return re.compile(regex).sub(substitute, text)
...
>>> replace("1 foo 2 bar 1 baz", [("1", "one"), ("2", "two")])
'one foo two bar one baz'
More information about the Python-list
mailing list