0

Any idea how to not include anything with None? I am trying to just pull in IP addresses at this point, but I don’t want to include empty elements.

My API Response

[{'name': '', 'serial': 'Q2KN-xxxx-438Z', 'mac': '0c:8d:db:c3:ad:c8', 'networkId': 'L_6575255xxx96096977', 'model': 'MX64', 'address': '', 'lat': 38.4180951010362, 'lng': -92.098531723022, 'notes': '', 'tags': '', 'wan1Ip': '47.134.13.195', 'wan2Ip': None}, {'name': '', 'serial': 'Q2PD-xxx-QQ9Y', 'mac': '0c:8d:db:dc:ed:f6', 'networkId': 'L_657525545596096977', 'model': 'MR33', 'address': '', 'lat': 38.4180951010362, 'lng': -92.098531723022, 'notes': '', 'tags': '', 'lanIp': '10.0.0.214'}]

Iterating through elements and selecting certain fields

response = requests.request("GET", url + id + '/devices', headers=headers)
data = response.json()
for item in data:
  keys = [item.get(x) for x in ['wan1Ip', 'model', 'lanIp', 'wan2Ip']]
  print(*keys, sep="\n", file=sys.stdout)

My output is:

47.134.13.195
MX64
None
None
None
MR33
10.0.0.214
None

My desired output is:

47.134.13.195
10.0.0.214

I’ve tried adding a re.findall for ip addresses, but not sure that’s going to work for me. I’ve also tried to add operators for not in None and several other things.

re.findall(“(?:[\d]{1,3}).(?:[\d]{1,3}).(?:[\d]{1,3}).(?:[\d]{1,3})?“,string2 )

Update I've changed my line to keys = [item.get(x) for x in ['wan1Ip', 'model', 'lanIp', 'wan2Ip', '{}']if x in item]

Obviously, I still have non IP addresses in my output, but I can select the elements that have IP addresses only. My main issue was None. I will also try some of the other suggestions.

ekad
  • 14,436
  • 26
  • 44
  • 46
one3y3
  • 5
  • 3
  • Your if clause should be `if x in item and item[x]` I also prefer to manipulate IP addresses as IP addresses [rather than strings](https://docs.python.org/3/library/ipaddress.html). – Jared Smith Aug 12 '19 at 01:53

4 Answers4

0

Add a filter to your list comprehension to check to see if key x is in item.

for item in data:
  keys = [item.get(x) for x in ['wan1Ip', 'model', 'lanIp', 'wan2Ip'] if x in item]
  print(*keys, sep="\n", file=sys.stdout)
azundo
  • 5,902
  • 1
  • 14
  • 21
  • Wow! Could it be that simple? So, I added that line in and it remove most of the None output. Oddly enough I had one None still in my output, which doesn't make any sense to me. ```47.13.135.195 MX64 None MR33 10.0.0.214``` – one3y3 Aug 12 '19 at 01:34
  • Oh - it's not from the element data - it's the actual element wan2Ip doesn't exist in my second list. – one3y3 Aug 12 '19 at 01:37
  • I added '{}' - that should work, correct? ```keys = [item.get(x) for x in ['wan1Ip', 'model', 'lanIp', 'wan2Ip' '{}']if x in item]``` – one3y3 Aug 12 '19 at 01:40
0

Search each key ipv4 with regex(https://stackoverflow.com/a/5284410/6250402) and check key is None with item.get(x) or ''

import re

myRegex = re.compile(r'\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}\b')
# data here

for item in data:

    keys = [item.get(x) for x in ['wan1Ip', 'model', 'lanIp', 'wan2Ip'] if myRegex.search(item.get(x) or '')]
    print(*keys, sep="\n", file=sys.stdout)
hong4rc
  • 3,999
  • 4
  • 21
  • 40
  • Thank you Hongarc - do you know if there is any benefit of doing it one way or the other? Appreciate your help! – one3y3 Aug 12 '19 at 01:43
0

You could add this condition to the end of your list comprehension:

keys = [item.get(x) for x in ['wan1Ip', 'model', 'lanIp', 'wan2Ip'] if item.get(x) is not None]

The output will be what you want.

Gammaliel
  • 21
  • 1
  • 5
0

Could you try this:

    >> data = response.json()
    >> keys = [x.get(key) for key in ['wan1Ip', 'model', 'lanIp', 'wan2Ip'] for x in data if x.get(key)]
    >> print(keys)
    >> ['47.134.13.195', 'MX64', 'MR33', '10.0.0.214']
Nidhin Bose J.
  • 1,092
  • 15
  • 28