Reputation: 31
What's the pythonic way to implement this:
s = "thisismystring"
keys = [4, 2, 2, 6]
new = []
i = 0
for k in keys:
new.append(s[i:i+k])
i = i+k
This does give me ['this', 'is', 'my', 'string']
as I need but I fell there's a more elegant way to do it. Suggestions?
Upvotes: 3
Views: 75
Reputation: 41872
Just because I believe there have to be ways to do this without explicit loops:
import re
s = "thisismystring"
keys = [4, 2, 2, 6]
new = re.findall((r"(.{{{}}})" * len(keys)).format(*keys), s)[0]
print(new)
OUTPUT
('this', 'is', 'my', 'string')
Upvotes: 1
Reputation: 28596
Could use islice
. Probably not efficient, but maybe at least interesting and simple.
>>> from itertools import islice
>>> s = 'thisismystring'
>>> keys = [4, 2, 2, 6]
>>> it = iter(s)
>>> [''.join(islice(it, k)) for k in keys]
['this', 'is', 'my', 'string']
Upvotes: 3
Reputation: 1121814
You could use itertools.accumulate()
, perhaps:
from itertools import accumulate
s = "thisismystring"
keys = [4, 2, 2, 6]
new = []
start = 0
for end in accumulate(keys):
new.append(s[start:end])
start = end
You could inline the start
values by adding another accumulate()
call starting at zero:
for start, end in zip(accumulate([0] + keys), accumulate(keys)):
new.append(s[start:end])
This version can be made into a list comprehension:
[s[a:b] for a, b in zip(accumulate([0] + keys), accumulate(keys))]
Demo of the latter version:
>>> from itertools import accumulate
>>> s = "thisismystring"
>>> keys = [4, 2, 2, 6]
>>> [s[a:b] for a, b in zip(accumulate([0] + keys), accumulate(keys))]
['this', 'is', 'my', 'string']
The double accumulate could be replaced with a tee()
, wrapped in the pairwise()
function from the itertools
documentation:
from itertools import accumulate, chain, tee
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return zip(a, b)
[s[a:b] for a, b in pairwise(accumulate(chain([0], keys)))]
I threw in an itertools.chain()
call to prefix that 0 starting position, rather than create a new list object with concatenation.
Upvotes: 6
Reputation: 16184
I would use enumerate
for that, with accumulating:
[s[sum(keys[:i]): sum(keys[:i]) + k] for i, k in enumerate(keys)]
With your example:
>>> s = "thisismystring"
>>> keys = [4, 2, 2, 6]
>>> new = [s[sum(keys[:i]): sum(keys[:i]) + k] for i, k in enumerate(keys)]
>>> new
['this', 'is', 'my', 'string']
Upvotes: 3