0

I have translated a program from javascript to python 3.9 and I am only missing sorting the result, but I just can't get any further.

The list consists of dicts that has an id "components", which is itself a list.

recipe.components.sort((a, b) => (a.components ? 1 : 0) - (b.components ? 1 : 0))

If i understood the java code correctly, then all elements (a.components) that are an empty list should be at the beginning and all that have elements in their list should be at the end, but that's the small problem, because you can reverse it with .reverse() anyway.

recipe.components = [{
    "id": 123,
    "components": [{"id": 1, "components": []}]
},
{
    "id": 124,
    "components": [{"id": 2, "components": []}, {"id": 3, "components": []}]
},
{
    "id": 125,
    "components": []
},
{
    "id": 126,
    "components": [{"id": 1, "components": []}]
}]

Does anyone know how to write this most elegantly in Python?

--- Edit ---

I solved it like this:

recipe["components"].sort(key=lambda a: 1 if a.get("components") else 0)
  • 2
    You are probably looking for this [Does Python have a ternary conditional operator?](https://stackoverflow.com/questions/394809/does-python-have-a-ternary-conditional-operator) – Yoshikage Kira Jun 15 '21 at 17:46
  • 1
    You don't seem to have written it in Python at all. – Scott Hunter Jun 15 '21 at 17:50
  • 2
    Wait, you changed the code? `components` consists of objects with a `components` property? – trincot Jun 15 '21 at 17:51
  • The argument of the `Array.sort()` function in js takes two elements to sort and returns the comparison of the two -- if `a > b`, return `1`. If they're equal, return `0`, if `b > a`, return `-1`. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort In python, you can specify a `key` argument to the `sorted()` function that does something similar, but it doesn't take two arguments to compare -- just one argument that you can return a "fitness" for, and it'll sort by this fitness. How you implement this is up to you. "Translate this" is not a SO issue. – Pranav Hosangadi Jun 15 '21 at 17:54

1 Answers1

1

For your original code:

components.sort((a, b) => (a ? 1 : 0) - (b ? 1 : 0))

...it could be:

components.sort(key=bool)

After your edit to:

components.sort((a, b) => (a.components ? 1 : 0) - (b.components ? 1 : 0))

... I will assume that the corresponding Python list has objects with an attribute components:

components.sort(key=lambda a: bool(a.components))
trincot
  • 317,000
  • 35
  • 244
  • 286
  • 1
    I do not think the answer was so simple, I don't understand the downvotes and I think it's completely unrelated to the ternary operator (unless you want to use `functools.cmp_to_key()`) – Marco Sulla Jun 15 '21 at 18:13
  • Yes, I have revised the question again, because I noticed that I had copied the wrong code. I have updated the text and it is a list and it is sorted by whether the attribute "components" is an empty list or whether it has items. I'm also not exactly sure how the list is sorted then in javascript, but I think the dicts with empty lists should be at the beginning, right? – Philipp Reuter Jun 15 '21 at 18:24
  • If you provide the python code for initialising the list, I can accomodate the answer to that – trincot Jun 15 '21 at 19:06
  • That would unfortunately take too long, because it is generated by several modules. But here is an example structure, actually it is not so complicated, but I must admit, my question was not very good and precisely asked. I have added the example to the question, hope it helps. – Philipp Reuter Jun 15 '21 at 19:41
  • Made it work: `recipe["components"].sort(key=lambda a: 1 if a.get("components") else 0)` – Philipp Reuter Jun 15 '21 at 19:56