0

it seems to be a very basic question but I can't find an answer.

I'm trying to build a list of strings from a split on a bigger string.

input = 'I#have#a#problem'
result = [s for s in input.split('#')]
>>> ['I', 'have', 'a', 'problem']

That works perfectly. The problem is, sometimes the input is not a string, but None. To avoid the python error AttributeError: AttributeError: 'NoneType' object has no attribute 'split', I tried to add an if statement, but that doesn't do anything to prevent the error.

input = None
result = [s for s in input.split('#') if input]
>>> AttributeError: 'NoneType' object has no attribute 'split'

Is there a way to do that while keeping the one-liner ?

Thanks

Kevin B.
  • 43
  • 1
  • 7
  • 1
    That's for filtering items in the for statement. Try parenthesizing differently: `[s for s in input.split('#')] if input else None` – Felix Nov 02 '20 at 10:05
  • 1
    Also, you should really use `if input is not None else None` - see [pep8](https://www.python.org/dev/peps/pep-0008/#id51) – SiHa Nov 02 '20 at 10:12
  • And a correction to the comment above, the list comprehension isn't really needed, because split returns a list already. So `input.split('#') if input else None`. – Felix Nov 02 '20 at 10:12
  • @SiHa That's also a good point, unless you have such inputs that they can be *falsy* and you want the result to still be None. – Felix Nov 02 '20 at 10:14
  • 1
    see https://stackoverflow.com/questions/394809/does-python-have-a-ternary-conditional-operator and https://docs.python.org/3/reference/expressions.html#conditional-expressions – Wups Nov 02 '20 at 10:14
  • @Felix True, although, I would suggest that if that's possible you should be refactoring your code. – SiHa Nov 02 '20 at 10:16
  • @SiHa Fair enough :D – Felix Nov 02 '20 at 10:17

3 Answers3

2
if input: result = input.split("#")

This should work. No need to put brackets! Or, if you want to define result anyway:

result = input.split("#") if input else None
Daniel
  • 487
  • 4
  • 11
  • Note that result is not defined after doing this if the input is none. Could be dangerous. – Felix Nov 02 '20 at 10:09
  • Also, one line ifs like this are considered bad style in Python. – Felix Nov 02 '20 at 10:09
  • Well, that's what the user asked, a one-line solution – Daniel Nov 02 '20 at 10:10
  • 1
    True. But that's no reason to suggest suboptimal solutions. Look at my comment though, which has the generally accepted one-line if *with* an else statement. I don't mean to belittle your answer, but I believe it could be done better. – Felix Nov 02 '20 at 10:11
2

First of all there is no need to do this : [s for s in input.split('#')] because split() returns already a list input.split('#') is enough But for the None issue, here is my suggestion :

result = inputStr.split('#') if inputStr else None

And here we go : enter image description here

kaouther
  • 369
  • 1
  • 11
0

Don't use input as variable name, return a else None if it is None (input is Input here):

[[s for s in Input.split('#')] if Input else None]

Another list Comprehension less edition:

if Input: result = Input.split("#")
Wasif
  • 14,755
  • 3
  • 14
  • 34