3

How should I extract numbers only from

a = ['1 2 3', '4 5 6', 'invalid']

I have tried:

mynewlist = [s for s in a if s.isdigit()]
print mynewlist

and

for strn in a:
    values = map(float, strn.split())
print values

Both failed because there is a space between the numbers.

Note: I am trying to achieve output as:

[1, 2, 3, 4, 5, 6]
Eugene Yarmash
  • 131,677
  • 37
  • 301
  • 358
labmat
  • 193
  • 1
  • 1
  • 10
  • Are numbers separated by spaces only or do you expect there might be something else, like a comma or something? – Dunno Oct 28 '16 at 15:02
  • what are u getting using `values = map(float, strn.split())` ? – levi Oct 28 '16 at 15:02
  • @Dunno: yes they are separated by space instead of a comma – labmat Oct 28 '16 at 15:05
  • @levi I get ValueError: could not convert string to float: invalid – labmat Oct 28 '16 at 15:06
  • 1
    It doesn't matter much in this case because why your code didn't work is obvious, but you should get in the habit of including full stack traces and detailed descriptions of how your code is failing in your SO questions. When you ask SO questions about more complex problems in the future, saying your code "failed" is probably going to result in a closed question because its not nearly detailed enough. – skrrgwasme Oct 28 '16 at 15:11

6 Answers6

7

I think you need to process each item in the list as a split string on whitespace.

a = ['1 2 3', '4 5 6', 'invalid']
numbers = []
for item in a:
    for subitem in item.split():
        if(subitem.isdigit()):
            numbers.append(subitem)
print(numbers)

['1', '2', '3', '4', '5', '6']

Or in a neat and tidy comprehension:

[item for subitem in a for item in subitem.split() if item.isdigit()]
paleolimbot
  • 341
  • 1
  • 3
3

That should do for your particular case since you include a string within list. Therefore you need to flatten it:

new_list = [int(item) for sublist in a for item in sublist if item.isdigit()]
SuperRafek
  • 31
  • 3
3

Assuming the list is just strings:

[int(word) for sublist in map(str.split, a) for word in sublist if word.isdigit()]
Patrick Haugh
  • 55,247
  • 13
  • 83
  • 91
2

With the help of sets you can do:

>>> a = ['1 2 3', '4 5 6', 'invalid']
>>> valid = set(" 0123456789")
>>> [int(y) for x in a if set(x) <= valid for y in x.split()]
[1, 2, 3, 4, 5, 6]

This will include the numbers from a string only if the string consists of characters from the valid set.

Eugene Yarmash
  • 131,677
  • 37
  • 301
  • 358
0
mynewlist = [s for s in a if s.isdigit()]
print mynewlist

doesnt work because you are iterating on the content of the array, which is made of three string:

  1. '1 2 3'
  2. '4 5 6'
  3. 'invalid'

that means that you have to iterate again on each of those strings.

you can try something like

mynewlist = []
for s in a:
    mynewlist += [digit for digit in s if digit.isdigit()] 
a.costa
  • 879
  • 1
  • 7
  • 18
  • You should avoid using the word "array" in variable names that have lists. Arrays and lists are different data structures with different attributes and capabilities. – skrrgwasme Oct 28 '16 at 15:14
  • Was there an early revision that used it? Because it's not there now or in the question revision history. – skrrgwasme Oct 28 '16 at 15:19
0

One liner solution:

new_list = [int(m) for n in a for m in n if m in '0123456789']
jtitusj
  • 2,976
  • 3
  • 22
  • 40