1
strings = ["1 asdf 2", "25etrth", "2234342 awefiasd"] #and so on

Which is the easiest way to get [1, 25, 2234342]?

How can this be done without a regex module or expression like (^[0-9]+)?

6
  • 2
    What if there is a string "asdf" in the input? Should it be 0, or not appear in the result list? Commented Feb 22, 2011 at 6:13
  • @Mikel, good point; the latter makes more sense to me, so I added a line to produce that result. Commented Feb 22, 2011 at 6:28
  • Why do you want a solution without using regular expressions? Usecase? Commented Feb 22, 2011 at 6:57
  • @ Mikel, There is always at least one digit at the beginning. Commented Feb 22, 2011 at 7:38
  • @Andreas Jung, Regex seems too much for such simple task. Wanted to find elegant solution without regex. Commented Feb 22, 2011 at 7:40

5 Answers 5

2

One could write a helper function to extract the prefix:

def numeric_prefix(s):
    n = 0
    for c in s:
        if not c.isdigit():
            return n
        else:
            n = n * 10 + int(c)
    return n

Example usage:

>>> strings = ["1asdf", "25etrth", "2234342 awefiasd"]
>>> [numeric_prefix(s) for s in strings]
[1, 25, 2234342]

Note that this will produce correct output (zero) when the input string does not have a numeric prefix (as in the case of empty string).

Working from Mikel's solution, one could write a more concise definition of numeric_prefix:

import itertools

def numeric_prefix(s):
    n = ''.join(itertools.takewhile(lambda c: c.isdigit(), s))
    return int(n) if n else 0
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, "takewhile" is what I need
2
new = []
for item in strings:
    new.append(int(''.join(i for i in item if i.isdigit())))


print new
[1, 25, 2234342]

5 Comments

But it will check each letter in string. "1 asdf 1" will turn into 11 instead of 1
If the string was "1 asdf 2" would the result be 1 or 2?
@CSZ: If the string is "1 asdf 1" what should (or do you expect) the result to be? 1 or 11? These are your strings...
See itertools.takewhile for one way to fix the "1 asdf 2" problem.
If you're going to give a list comprehension solution, might as well go all out (: [int(x) for x in ["".join([c for c in s if c.isdigit()]) for s in strings]]
1

Basic usage of regular expressions:

import re

strings = ["1asdf", "25etrth", "2234342 awefiasd"]

regex = re.compile('^(\d*)')

for s in strings:

  mo = regex.match(s)

  print s, '->',  mo.group(0)

1asdf -> 1

25etrth -> 25

2234342 awefiasd -> 2234342

3 Comments

-1. Third line of question reads "How can this be done without a regex module or expression like (^[0-9]+)?" It's pretty obvious CSZ is asking for an answer that does not use re.
Completely worthless thread since there is zero reason for NOT USING a regular expressions here.
Agreed. But /that/ should have been your answer.
1

Building on sahhhm's answer, you can fix the "1 asdf 1" problem by using takewhile.

from itertools import takewhile

def isdigit(char):
  return char.isdigit()

numbers = []
for string in strings:
    result = takewhile(isdigit, string)
    resultstr = ''.join(result)
    if resultstr:
        number = int(resultstr)
        if number:
            numbers.append(number)

1 Comment

Note that Adeel Soomro's answer is probably simpler, provided it's OK for a string containing no digits to appear as None in the result list.
1

So you only want the leading digits? And you want to avoid regexes? Probably there's something shorter but this is the obvious solution.

nlist = []
for s in strings:
    if not s or s[0].isalpha(): continue
    for i, c in enumerate(s):
        if not c.isdigit():
            nlist.append(int(s[:i]))
            break
    else:
        nlist.append(int(s))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.