Home > Back-end >  parsing list with mixed type of data
parsing list with mixed type of data

Time:09-24

I have an issue with a list containing mixed data types (int and str) like this one:

['C2960X-STACK      ', 'FOC21444KYR', 'Switch 2 - FlexStackPlus Module', 'WS-C2960X-48FPS-L', 'FCW2145B4CB', 2, 'C2960X-STACK      ', 'FOC214561CP', 'Switch 1 - FlexStackPlus Module', 'WS-C2960X-48FPS-L', 'FCW2144B01G', 1]

This is an example, I received (from an API) longer lists and for some device lists with another format (just discovered it now) where the 3rd field is different. Instead of having a single int (1,2 or 3 and so one) I have "Switch 1", "Switch 2" and so on.

The best would have an order like (based only on 3rd item of the tupples) (or reversed order):

3,2,1,"Switch 1 - - FlexStackPlus Module", "Switch 2 - - FlexStackPlus Module", "Switch 3 - - FlexStackPlus Module"

Or for the other type of list (or reversed order):

"Switch 3","Switch 2","Switch 1","Switch 1 - - FlexStackPlus Module", "Switch 2 - - FlexStackPlus Module", "Switch 3 - - FlexStackPlus Module"

I'm trying to order the list (name self.thisParts) by device (group of 3 elements in a row) but some elements are int and are probably the reason I'm stuck.

I do the following

swNr = 1
while swNr <= len(thisStack) :
    while self.thisParts :
        self.findSw(swNr)
        self.findSwParts(swNr)
        swNr  = 1


def findSw(self, swNR):
    for i in range (0, (len(self.thisParts)//3)):
        if (self.thisParts[i 2] == str(swNR)) or (self.thisParts[i 2] == ("Switch " str(swNR))) :
            self.orderedParts.append(self.thisParts[(i*3):(i*3 3)])
            del self.thisParts[(i*3):(i*3 3)]


def findSwParts(self, swNR):
    for i in range (0, (len(self.thisParts)//3)):
        if ("Switch " str(swNR)) in self.thisParts[i 2] :
            self.orderedParts.append(self.thisParts[(i*3):(i*3 3)])
            del self.thisParts[(i*3):(i*3 3)]

But I have the following error:

File "/var/www/html/GenericDeviceReportTest.py", line 166, in findSwParts
if substring in self.thisParts[i 2] :
TypeError: argument of type 'int' is not iterable

...something went wrong!

I think it's because I have string and int in the field I'm searching, so I tried to convert the list to str but it seems to not work neither:

self.thisParts  = list(map(str, self.thisParts))

TypeError: 'bool' object is not iterable

...something went wrong!

I have the same error if I try with a while/for (read and convert all to str) but same error each time (last one I listed).

Thanks for your help !

CodePudding user response:

Assuming you're happy with alphanumerical ordering (where numbers come before letters), you can do the following (leaving of self):

thisParts = ['C2960X-STACK     ', 'FOC21444KYR', 'Switch 2 - FlexStackPlus Module', 'WS-C2960X-48FPS-L', 'FCW2145B4CB', 2, 'C2960X-STACK      ', 'FOC214561CP', 'Switch 1 - FlexStackPlus Module', 'WS-C2960X-48FPS-L', 'FCW2144B01G', 1]

# Create groups of 3-tuples 
thisParts = list(zip(thisParts[::3], thisParts[1::3], thisParts[2::3]))

# Sort the list, temporarily turning the tuples into strings
thisParts.sort(key=str)
# But, the comments seem to suggest an ordering by the third part of the device tuple. That would mean using the following sorting instead
thisParts.sort(key=lambda device: str(device[2]))

# Now to get back to the original list, by unnesting the list of tuples
thisParts = [item for device in thisParts for item in device]

and thisParts will be sorted in-place, per subset of 3 items (device):

['C2960X-STACK      ', 'FOC21444KYR', 'Switch 2 - FlexStackPlus Module', 'C2960X-STACK      ', 'FOC214561CP', 'Switch 1 - FlexStackPlus Module', 'WS-C2960X-48FPS-L', 'FCW2144B01G', 1, 'WS-C2960X-48FPS-L', 'FCW2145B4CB', 2]

And for the one-liner:

thisParts = [item for device in sorted(zip(thisParts[::3], thisParts[1::3], thisParts[2::3]), key=str) for item in device]
  • Related