Print a sorted list of devices

Solved
eroche
Getting noticed

Print a sorted list of devices

Hi All

 

Looking to print a sorted list of device based on the device name, item['name'] field:

 

for item in response:    
	
	if value.lower() in item['model'] and item['name'] != '':
		print(f"{item['serial']}: {item['name']}")
	elif value.title() in item['model'] and item['name'] != '':
		print(f"{item['serial']}: {item['name']}")
	else:
		if value.upper() in item['model'] and item['name'] != '':
			print(f"{item['serial']}: {item['name']}")

 

I tried the field.sort(), sorted(field) but closes I got was it sorted literally every little in my list.

 

Please advise 🙂

 

1 Accepted Solution
sungod
Head in the Cloud

Just a guess, but if a device does not have a name assigned, many API calls will return an object called None instead of the name. None is not a string, it's type is NoneType.

 

I'd think this is high probability if you are using a call that returns inventory as unused devices will not have a name.

 

The same type of thing can happen with other calls/elements, you usually find out the hard way that an API call can do this!

 

In dashboard UI, it defaults missing names to the device MAC address, but the API generally does not do this, if there is no name, you get None.

 

So in your code, the error is because None is not acceptable.

 

I've not tested, but try this instead, it might work...

 

SortedListOfDevices = sorted(response, key=lambda d: d['mac'] if d['name'] is None else d['name'])

 

 

View solution in original post

11 Replies 11
rhbirkelund
Kind of a big deal
Kind of a big deal

The reponse is usually a list, where each element is a dictionary. So you need to sort the list based on values that are further "down the chain", which are in a dictionary.

 

You can sort the list using the sorted() method and pass a lambda function as key;

newlist = sorted(list_to_be_sorted, key=lambda d: d['name'])

https://stackoverflow.com/questions/72899/how-to-sort-a-list-of-dictionaries-by-a-value-of-the-dicti... 

LinkedIn ::: https://blog.rhbirkelund.dk/

Like what you see? - Give a Kudo ## Did it answer your question? - Mark it as a Solution 🙂

All code examples are provided as is. Responsibility for Code execution lies solely your own.

Thank you!

 

Not to be a nimrod but how would I do that with this scenario? Its really not a straightforward thing, at least to me. Would it be......oh and 'value' is the variable for the input I am searching for

newlist = sorted(value, key=lambda d: d['item(name)'])

or

newlist = sorted(value, key=lambda d: d['name']

 

Thoughts?

rhbirkelund
Kind of a big deal
Kind of a big deal

Assuming you're getting a list of all appliances in a single organization, and want to sort according to name, it'd be like this

organization_id = ""

response = dashboard.organizations.getOrganizationInventoryDevices(
        organization_id, 
        total_pages='all',
        productTypes = ['appliance']
    )

SortedListOfDevices = sorted(response, key=lambda d: d['name'])

 

LinkedIn ::: https://blog.rhbirkelund.dk/

Like what you see? - Give a Kudo ## Did it answer your question? - Mark it as a Solution 🙂

All code examples are provided as is. Responsibility for Code execution lies solely your own.

Great thank you much apricated! 

Ok so I tried that but it is now giving me an error of 

Traceback (most recent call last):
File "/mnt/m2ssd/python/meraki_get_devices.py", line 21, in <module>
SortedListOfDevices = sorted(response, key=lambda d: d['name'])
                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: '<' not supported between instances of 'NoneType' and 'str'

Thoughts?

 

response = dashboard.organizations.getOrganizationInventoryDevices(
    organization_id, total_pages='all'
)

SortedListOfDevices = sorted(response, key=lambda d: d['name'])

value = input("Find: ")

for item in SortedListOfDevices:    
	
	if value.lower() in item['model'] and item['name'] != '':
		print(f"{item['serial']}: {item['name']}")
	elif value.title() in item['model'] and item['name'] != '':
		print(f"{item['serial']}: {item['name']}")
	else:
		if value.upper() in item['model'] and item['name'] != '':
			print(f"{item['serial']}: {item['name']}")

 

sungod
Head in the Cloud

Just a guess, but if a device does not have a name assigned, many API calls will return an object called None instead of the name. None is not a string, it's type is NoneType.

 

I'd think this is high probability if you are using a call that returns inventory as unused devices will not have a name.

 

The same type of thing can happen with other calls/elements, you usually find out the hard way that an API call can do this!

 

In dashboard UI, it defaults missing names to the device MAC address, but the API generally does not do this, if there is no name, you get None.

 

So in your code, the error is because None is not acceptable.

 

I've not tested, but try this instead, it might work...

 

SortedListOfDevices = sorted(response, key=lambda d: d['mac'] if d['name'] is None else d['name'])

 

 

eroche
Getting noticed

That is true. I do have 1 that is named NONE. I will give it at try. Thanks much!

eroche
Getting noticed

That did it. Thanks.

rhbirkelund
Kind of a big deal
Kind of a big deal

Do you have devices in your inventory that aren't named? That's probably the reason.

rhbirkelund_1-1721325214041.png

 

 

rhbirkelund_0-1721325156194.png

 

LinkedIn ::: https://blog.rhbirkelund.dk/

Like what you see? - Give a Kudo ## Did it answer your question? - Mark it as a Solution 🙂

All code examples are provided as is. Responsibility for Code execution lies solely your own.

Yeah, Sungod beat you to the answer. 

eroche
Getting noticed

So I am entering a value that I want to filter on, VALUE. That works as expected but now would like to sort on the item('name') field from my query. The data is a list of my switches. So the filtered list comes out as <serail#>:<name>. I understand the sorted() option but the way my fields are named I can't seen to get it to work. Here is my code again. I added the input line at the top this time.

 

value = input("Find: ")


for item in response:    
	
	if value.lower() in item['model'] and item['name'] != '':
		print(f"{item['serial']}: {item['name']}")
	elif value.title() in item['model'] and item['name'] != '':
		print(f"{item['serial']}: {item['name']}")
	else:
		if value.upper() in item['model'] and item['name'] != '':
			print(f"{item['serial']}: {item['name']}")
Get notified when there are additional replies to this discussion.
Welcome to the Meraki Community!
To start contributing, simply sign in with your Cisco account. If you don't yet have a Cisco account, you can sign up.