0

I have an object like this

ds_obj = {
              "Labels" : 
                [ 
                    {
                        "Label" : "pop",
                        "People" : {
                          "Composer" : "John"
                        },
                    },
                    {
                        "Label" : "classical",
                        "People" : {
                          "Composer" : [ "Johann", "Jason" ]
                        },
                    },
                    {
                        "Label" : "classical-2",
                        "People" : {
                          "Composer" : [ "Jacob" ]
                        },
                    }        
                ]
            }    

I need to iterate thru each of the labels and perform some actions on each of the composers, but first I need to find out if each label has a single composer or multiple. To do this I am running the following code to find out if the key Composer has an array or a string. If it has an array, I will run a nested loop thru it and work with each composer. The code below however is calling out every value as an array. What is wrong with my code? Is there a more efficient way to do this?

    for label in ds_obj ['Labels']:
        if hasattr(label['People']['Composer'], "__len__"):
            print('IS ARRAY')
        else:
            print('NOT Array')
                    
 
user20358
  • 14,182
  • 36
  • 114
  • 186
  • `["Johann", "Jason"]` is a list (https://docs.python.org/3/library/stdtypes.html#list) rather than an array (https://docs.python.org/3/library/array.html). – slothrop Mar 10 '23 at 19:02
  • You shouldn't let the value be a string; even if it's just one person, you should still store it as a list `["John"]`, so that consumers don' have to worry about values of different types. – chepner Mar 10 '23 at 19:45

2 Answers2

2

Use:

if isinstance(label['People']['Composer'], list):

Python strings also have a __len__ attribute so your code is true for both lists and strings.

Jeff
  • 1,234
  • 8
  • 16
0

You're currently checking if composer has a length. Both strings and lists have lengths, so hasattr(..., '__len__') will return True in both cases.

You can just check if the type is equal to List.:

for label in ds_obj ['Labels']:
    if type(label['People']['Composer']) is list:
        print('Array')
    else: 
        print('NOT Array')
ae_bu
  • 92
  • 3