1

I'm wracking my brain with this. I need to iterate through a nested list (a list of lists, so only one level of sublist) to check if an entry is a positive or negative integer. If it is, I need to convert it to an int. The catch is that some other list elements contain numbers, so I can't just convert a list element containing numbers to an int because I get an error.

I tried this:

aList = ['a3','orange','-1','33']    
for aLine in aList:
    for token in aLine:
        if token.isdecimal() == True:
            map(int, aLine)
        elif token in "0123456789" and token.isalpha() == False:
            map(int, aLine)

...Which did absolutely nothing to my list.

I'm hoping to get this kind of output:

['a3', 'orange', -1, 33]
You're awesome
  • 301
  • 2
  • 16
leafgreen
  • 11
  • 3

4 Answers4

2

An easy way to check if a string s is an integer is by doing s.lstrip('+-').isdigit() which returns True/False. If the response is True you can cast it to int(s) which creates an integer.

You can create a new list from the responses or replace the item in the existing list if you have the index value. Here's a simple implementation.

aList = ['a3','orange','-1','33']
bList = []
for s in aList:
    if s.lstrip('+-').isdigit():
        bList.append(int(s.lstrip('+-'))
    else:
        bList.append(s)
print bList

The result of bList is as follows

>>> bList
['a3', 'orange', -1, 33]
Sudheesh Singanamalla
  • 2,283
  • 3
  • 19
  • 36
  • In the interests of being Pythonic: There is no need for `==True`, just `if s.lstrip('+-').isdigit():`. – roganjosh Nov 21 '17 at 04:46
  • Unlikely to ever come up, but `'++1'.lstrip('+-').isdigit() == True`, even though `int('++1')` is invalid – Patrick Haugh Nov 21 '17 at 04:47
  • @roganjosh agreed! Made the correction. My intention was to clarify to the OP about the `True`. @Patrick Haugh I Agree `++1` would make the casting invalid. Maybe a good idea would be to do `int(s.lstrip('+-'))` then, instead of `int(s)` – Sudheesh Singanamalla Nov 21 '17 at 04:51
1

This probably is not the most pythonic answer but it works:

assume

x = [['2','-5'],['a23','321','x12']]

the code is:

output = []
for row in x:
    temp = []
    for element in row:
        try:
            temp.append(int(element))
        except ValueError:
            temp.append(element)
    output.append(temp)

this gives you:

[[2, -5], ['a23', 321, 'x12']]
Alireza
  • 656
  • 1
  • 6
  • 20
  • Your approach using `try`/`except` is more pythonic than checking whether the conversion is possible beforehand. https://stackoverflow.com/questions/11360858/what-is-the-eafp-principle-in-python . I'm not sure why you've swapped to nested lists though. – roganjosh Nov 21 '17 at 04:48
  • @roganjosh the OP mentions nested list in the text of their question, but the sample data is not nested. – Patrick Haugh Nov 21 '17 at 04:50
  • @roganjosh It has mentioned that the data is list of list; and I said probably not pythonic because maybe there is a better way to iterate over elements of a list of lists rather than two for loops. if the code is pythonic, then I'm happy :) – Alireza Nov 21 '17 at 04:52
0

Anothere solution using list comprehension :

aList = ['a3', 'orange', '-1', '33']
results = [int(i) if i.lstrip('+-').isdigit() else i for i in aList]
print results

output:

['a3', 'orange', -1, 33]
Mahesh Karia
  • 2,045
  • 1
  • 12
  • 23
0

Same can be achieved in one line using list comprehension. ( Let me know if you need explanation)

aList = ['a3', '14', 'orange', '-1', '33', '0']

print([int(x) if x.lstrip('-').isnumeric() else x for x in aList ])

['a3', 14, 'orange', -1, 33, 0]