-3

I want to create an array inline like this: [x if arr[arr.index(x)+1] < x for x in arr] but when i do it python tells me i cant do that without having an else branch to my if statement.

The only "solution" I found was this: list(filter(lambda x: x != None, [x if arr[arr.index(x)+1] < x else None for x in arr]) but that is just ugly, and unnessecary. The reason i want to initialize the array this way is to keep the code short and clean, but now it would just be better to do a normal for loop.

Hopefully there are better ways to do this ;)

Kris10an
  • 548
  • 3
  • 23

2 Answers2

2

Your if is in the wrong position to correctly implement filter() with a list comprehension. Try this instead:

[x for x in arr if arr[arr.index(x)+1] < x]

See list comprehension vs. lambda + filter for details.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
  • This crashes with `arr = [1, 3, 2, 4]` with `IndexError: list index out of range` – Peter Wood Jan 03 '19 at 17:05
  • @PeterWood Good point. I was only showing how to fix the syntax error from the OP's code. I didn't worry about testing if this fix reveals a logic error. I leave the fix as an exercise for the OP and any other reader. – Code-Apprentice Jan 03 '19 at 20:35
2

You can loop through pairs from the list:

[a for a, b in zip(arr, arr[1:])
 if a < b]

For example:

>>> arr = [1, 3, 2, 4]
>>> [a for a, b in zip(arr, arr[1:])
...  if a < b]
[1, 2]

The accepted answer crashes with these values:

>>> [x for x in arr if arr[arr.index(x)+1] < x]
Traceback (most recent call last):
IndexError: list index out of range
Peter Wood
  • 23,859
  • 5
  • 60
  • 99
  • This is a very elegant solution that seems to almost match what the OP is doing. Note that this will eliminate the last element of the list because `zip()` terminates on the shortest of the input lists. This may not be the desired behavior. – Code-Apprentice Jan 03 '19 at 16:37
  • @Code-Apprentice The only way OP's code (and your fixed solution) wouldn't crash is if the last element was duplicated earlier in `arr`. But then the solution would be wrong as `index` would find the earlier value. – Peter Wood Jan 03 '19 at 17:04