Reputation: 33
I'm trying to find a way to split a number to list of odd number sequences:
num = "57483795478973"
for digit in num:
if int(digit)%2==0:
list_a = str.split(num,digit)
print (list_a)
but the result I'm getting is
['574', '379547', '973']
which includes the even numbers, and I don't understand what I'm doing wrong.
Upvotes: 1
Views: 899
Reputation: 35901
Here is a solution using the re
module:
>>> import re
>>> re.split('[02468]', '57483795478973')
['57', '', '3795', '7', '973']
The first argument, in this case, is effectively a list of delimiters - which are even numbers in your case. If you want to skip empty results:
>>>[r for r in re.split('[02468]', '57483795478973') if r]
['57', '3795', '7', '973']
And here is a way to calculate it by hand, using a generator:
def splitToOddSeqs(numbers):
seq = ""
for n in numbers:
if n not in "02468":
seq += n # as long as we have odd numbers, we accumulate
else:
if seq:
yield seq # we've found an even number - return one sequence
seq = ""
if seq:
yield seq # return last one (when input ends with odd digit)
Example usage:
>>> list(splitToOddSeqs('57483795478973'))
['57', '3795', '7', '973']
Upvotes: 5
Reputation: 11251
It sounds like the result you want is:
['57', '3795', '7', '973']
But every iteration through the loop, you replace list_a
with the most recent str.split(num, digit)
. Since 8
is the last even digit in num
, the final value of list_a
is str.split(num, '8')
- a string that's only split on 8's.
Passing your output through split
over and over again won't work either, because after the first split
, you're working with a list of strings instead of a single string.
I'm surprised Python doesn't provide a library function that splits on any of a set of characters. Looks like you'll need to write it yourself.
Also, your code does extra work by looping over the digits in num
instead of just looping over all the even digits once. If num
is very long, you'll end up splitting on the same digit over and over, wasting effort.
I wrote a less Pythonic, more C-like answer, but I like the answers using regex, itertools
, and generators better.
Upvotes: 0
Reputation: 107347
Alongside the other good answers , you can use itertools.groupby
(good if you are consider about performance ):
>>> import itertools
>>> l=[list(g) for k,g in itertools.groupby(num,lambda x : int(x)%2==0)]
>>> [''.join(i) for i in l if int(i[0])%2!=0]
['57', '3795', '7', '973']
Upvotes: 1
Reputation: 13158
You're calculating list_a
every time through the loop. The final time through the loop ('8') gives the result that you see. What you want is to split on '0', '2', '4' and '6' as well as '8'.
Upvotes: 1