0

The first part of my homework was to write code that does the following:

def car_make_and_models(all_cars: str) -> list:
    """
    Create a list of structured information about makes and models.

    For each different car make in the input string an element is created in the output list.
    The element itself is a list, where the first position is the name of the make (string),
    the second element is a list of models for the given make (list of strings).

    No duplicate makes or models should be in the output.

    The order of the makes and models should be the same os in the input list (first appearance).
    """
    if not all_cars:
        return []
    model_list = []
    cars = all_cars.split(",")
    for car in cars:
        car_make = car.split(" ")[0]
        car_model = " ".join(car.split(" ")[1:])
        car_makes = [item[0] for item in model_list]
        if car_make not in car_makes:
            model_list.append([car_make, [car_model]])
        elif car_model not in model_list[car_makes.index(car_make)][1]:
            model_list[car_makes.index(car_make)][1].append(car_model)
    return model_list


"Audi A4,Skoda Super,Skoda Octavia,BMW 530,Seat Leon Lux,Skoda Superb,Skoda Superb,BMW x5" 

=> 

[['Audi', ['A4']], ['Skoda', ['Super', 'Octavia', 'Superb']], ['BMW', ['530', 'x5']], ['Seat', ['Leon Lux']]]

In part 2, it is required to write a function add_cars with two parameters, where the 1st car_list is the output of the function above, and the 2nd all_cars is a string, for example "Audi A5,Audi A6". So, print(add_cars([['Audi', ['A4']], ['Skoda', ['Superb']]], "Audi A6,BMW A B C,Audi A4")) should give me [['Audi', ['A4', 'A6']], ['Skoda', ['Superb']], ['BMW', ['A B C']]]. However, I don't understand how to use the function above to write the add_cars function. Can someone help or guide?

0

3 Answers 3

1

You can lookup the maker name within your already built all_cars and then add your new entry it if does not exist yet.

def add_cars(all_cars: list, new_cars: str) -> list:
    if not new_cars or len(new_cars) == 0:
        return all_cars

    cars = new_cars.split(",")
    for car in cars:
        car_make = car.split(" ")[0]
        car_model = " ".join(car.split(" ")[1:])

        found = False
        for cm in all_cars:
            if (cm[0] == car_make):
                found = True
                if (car_model not in cm[1]):
                    cm[1].append(car_model)
                break

        # create a new entry if the maker is not part of the list yet
        if (not found):
            all_cars.append([car_make, [car_model]])

    return all_cars


ac = add_cars(ac, "Audi A5,Audi A6,Unknown XXX")
print(ac)

OUTPUT:

[['Audi', ['A4', 'A5', 'A6']], ['Skoda', ['Super', 'Octavia', 'Superb']], ['BMW', ['530', 'x5']], ['Seat', ['Leon Lux']], ['Unknown', ['XXX']]]
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks, this is really helpful. The only problem you have is if, for example, in the 2nd parameter there is a car that is not in the 1st parameter, then the function will skip this car, although it should not.
Indeed, it is a starting point for you to continue and cover all cases you are expected to :)
I think to solve this problem, one can add if not any(cm[0] == car_make for cm in all_cars): just before the for loop, i dont know however if this is the only way.
@Cornifer Added the case where the maker is not in the list yet \o/
1

Without lambda (which OP hasn't learned) or any additional imports you could do this:

def car_make_and_models(s):
    result = {}
    if s:
        for cmm in s.split(','):
            make, *models = cmm.split()
            result[make] = result.setdefault(make, set()).union(models)
    return [[k, list(v)] for k, v in result.items()]

s = "Audi A4,Skoda Super,Skoda Octavia,BMW 530,Seat Leon Lux,Skoda Superb,Skoda Superb,BMW x5"

print(car_make_and_models(s))

Output:

[['Audi', ['A4']], ['Skoda', ['Octavia', 'Superb', 'Super']], ['BMW', ['530', 'x5']], ['Seat', ['Leon', 'Lux']]]

Note:

The use of lists is inappropriate here. A dictionary would be much better

Comments

0

You can do with pythonic way like this,

In [65]: [[k, [i.split()[1] for i in l]]
    ...:         for k, l in groupby(
    ...:                 sorted(text.split(','), key=lambda x:x.split()[0]),
    ...:                 key=lambda x:x.split()[0])
    ...:         ]
Out[65]: 
[['Audi', ['A4']],
 ['BMW', ['530', 'x5']],
 ['Seat', ['Leon']],
 ['Skoda', ['Super', 'Octavia', 'Superb', 'Superb']]]

1 Comment

Thanks for your solution, unfortunately I don't understand it well and we haven't touched the lambda function yet.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.