Kevin KlariÄ‡ - 8 months ago 37

Python Question

I need to write a function in python, which returns the valid measurements for a list of numbers. A measure is invalid, if the closest other measurement is less that 0.1 second away. Also, the output list should be the same length as the length of the input list.

Thus:

`[5.1, 5.6, 6.0, 10.34, 10.37, 10.45, 12.5]`

`[True, True, True, False, False, False, True]`

I have approached the problem in the following fashion:

`list = [5.1, 5.6, 6.0, 10.34, 10.37, 10.45, 12.5]`

newlist = []

for i, j in zip(list, list[1:]):

if j - i >= .1:

newlist.append(True)

else:

newlist.append(False)

The problem is that this returns the following list:

`[True, True, True, False, False, True]`

`False`

How can I write this code differently?

Answer

Your assumption is incorrect. There's only 2 false measurements. The one at 10.37 and the one at 10.45. The measurement at `10.34`

is OK since it happens several seconds after the previous one.

Your result has 1 less value than the input list because you're comparing values 2 by 2.

It's a typical "intervals & values" problem. There's one less interval than values.

Write your test like this for better performance (list comprehension):

```
measures = [5.1, 5.6, 6.0, 10.34, 10.37, 10.45, 12.5]
print([measures[i+1]-measures[i]>0.1 for i in range(len(measures)-1)])
[True, True, True, False, False, True]
```

(your code creates a lot of useless temporary lists. Also avoid using `list`

as a variable)

However, if you want to invalidate *all* measurements which are too close, no fancy stuff, with sliding window:

```
measures = [5.1, 5.6, 6.0, 10.34, 10.37, 10.45, 12.5]
result = [True] * len(measures)
for i in range(len(measures)-1):
validity = (measures[i+1]-measures[i])>0.1
if result[i]: # don't overwrite an already invalidated value
result[i] = validity
result[i+1] = validity
print(result)
[True, True, True, False, False, False, True]
```

Details:

- creates a
`result`

array of the size of the input array (`*`

operator, nice) - iterates through all elements of the list but the last one
- compares current value and the "next" value to compute a
`validity`

flag (`True`

or`False`

) - if current
`result`

is already`False`

, it means that previous iteration already invalidated it, leave as-is, else set to`validity`

- set "next" result to
`validity`

(`i+1`

index)

No temporary list creation, should be fast enough.

Source (Stackoverflow)