0

I have 2 lists. One contains the names of components and the other has the names of the components and their description as a string. I need to sort the description list using the component list so they have the same order.

components = ['R500','R501','C500','C501','C502','R500']
description =['R500 "RES 1k 1% 0603"','R500 "RES 1k 1% 0603"','R508 "RES 9k 1% 06013"','R501 "RES 10k 1% 0604"','C500 "1uF 10% 0805"','C501 10uF 10% 0806','C502 "1nF 10% 0807"']

R508 should be discarded as it isn't in the components list.

C501 in the description list has deliberately been formatted different as the formatting is not always the same.

The output I expect is;

description = [
'R500 "RES 1k 1% 0603"',
'R501 "RES 10k 1% 0604"',
'C500 "1uF 10% 0805"',
'C501 "10uF 10% 0806"',
'C502 "1nF 10% 0807"',
'R500 "RES 1k 1% 0603",]
mark7378
  • 51
  • 7

2 Answers2

0

Your example data contains some values that don't start with any strings in components so this implementation just puts them at the start of the sorted list. The commented out section of code could be used if you want to raise an exception for this condition.

def find_startswith_index(value, indexes=components):
    for i, component in enumerate(components):
        if value.startswith(component):
            return i
    return -1
    # raise IndexError(f'Sort key not found for value "{value}"')

sorted(description, key=find_startswith_index)
# ['R508 "RES 9k 1% 06013"', 'R500 "RES 1k 1% 0603"', 'R500 "RES 1k 1% 0603"', 'R501 "RES 10k 1% 0604"', 'C500 "1uF 10% 0805"', 'C501 "10uF 10% 0806"', 'C502 "1nF 10% 0807"']
Justin Fay
  • 2,576
  • 1
  • 20
  • 27
0

You can use this:

description.sort(key=lambda x:components.index(x.split(' "')[0]))

But that won't work with you current example because don't have R508 in the components. Also, R500 appears twice, so it uses the first occurrence.

I think what you may want is actually this:

def findBySubstring(descriptions, sub):
    for d in descriptions:
        if sub in d:
            return d
    return "No description found"

result = [findBySubstring(descriptions, c) for c in components]
LeopardShark
  • 3,820
  • 2
  • 19
  • 33
  • This didn't work for me as some components have only a part number. How could this be edited so that if `' "'` didn't occur it would say 'Part number only'? – mark7378 Aug 08 '19 at 12:37
  • `x.split(y)` returns `[x]` if `y` is not in`x`, so it should still work. – LeopardShark Aug 08 '19 at 13:36
  • I get an error saying ValueError: `' C500 1u 10 10 ;' is not in list` – mark7378 Aug 08 '19 at 13:41
  • Do you have `' C500 1u 10 10 ;'` in your components list? If so, shouldn't it be formatted like `'C500 "1u 10 10 ;"'` or something? – LeopardShark Aug 08 '19 at 14:07
  • Not all descriptions have ' "'. I can't really change the formatting as that is how the descriptions are read in. Is there a way to implement an if statement that will either append the description output to some variable, else append 'No description found'? – mark7378 Aug 08 '19 at 14:19
  • I've edited my answer to do that. Warning though: searches blindly for the component names in the string, so it will match it if it appears in the 'description bit as well. – LeopardShark Aug 08 '19 at 15:26