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]