How to let a list append "nothing" (NOT NULL VALUE)

Question:

I have a function that will return different values depending on an if statement in the function. The returned value will be added to an existing list. However, in the function there is a case where I want the function to do nothing, i.e., the existing list will keep the same as if no function were called. Currently what I’m doing is the following, but I feel this looks messy and wondering if there is a better way to do:

import requests
def myfun(url):
    response=requests.get(url)
    code=response.status_code
    if code==503:
       time.sleep(3*random.random())
       value=None
    else:
       html=response.content()
       value=html['some tag']
    return (value,code)

lists=[]
for url in [my url pool]:
     (value,code)=myfun(url)
     lists.append(value)
     if code==503:
        lists.pop()

So basically what I do is to continuously visit some webpage, read some values then put the values in a growing list. However, sometime I get blocked (where Error Code 503 is given), then I want my code to sleep for a while then keep moving forward. In the case where I get 503 error code, nothing will be returned so the growing list will be the same. But I don’t know how to specify this case when I call the function, so I just set the returned values to None (or could be any value), then add them to the list but remove them from the list right after that. (So I use append() then pop() if the code is 503)

Asked By: Ruby

||

Answers:

Instead of appending the value, then checking for a 503 and removing the value…

lists.append(value)
if code==503:
   lists.pop()

Check that the response is not 503 and then append the value.

if code!=503:
   lists.append(value)
Answered By: TigerhawkT3

There are plenty of options; if you do care about the code, use the solution by @TigerhawkT3; if all you need is to append one value or none, you can e.g. just return None (and test for it), or return a (potentially empty) list, and .extend rather than .append

The latter option opens door to a particularly concise (while still readable) code:

import requests
def myfun(url):
    response=requests.get(url)
    code=response.status_code
    if code==503:
       ## why? time.sleep(3*random.random())
       return []
    else:
       html=response.content()
       return [html['some tag']]

lists=[value for url in [my url pool] for value in myfun(url)]
Answered By: alf

In Python, None is used to indicate no value. It is the same as NULL in other languages.

In your scenario, the correct application would be to add None when 503 is returned.

Ideally, you should return None and whatever error code is returned – as I assume the remainder of your code should fail if say, a 500 error is raised instead.

Once you have looped through all the URLs, simply filter out the ones that were successful; this way you can later decide what you do with that data (for example, log them separately or queue them for another run, etc).

Here is an approach that doesn’t discard “invalids”, but simply filters them out:

def myfun(url):
    value = None
    response=requests.get(url)
    code=response.status_code
    if code > 400:
       time.sleep(3*random.random())
       return (value, code)
    else:
       html=response.content()
       value=html['some tag']
    return (value,code)

lists=[]

for url in [my url pool]:
     lists.append(myfun(url))

# you can also do    
lists = [myfun(url) for url in my_url_pool]

successful = filter(lists, key=lambda x: x[0] != None)
blocked = filter(lists, key=lambda x: x[0] == 503)
Answered By: Burhan Khalid

I had a weird case where I needed to append nothing, and I just used the increment operator

a += []
Answered By: Mackie Messer
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.