Kevin KlariÄ‡ - 1 year ago 66
Python Question

# Return the "valid" numbers

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]`
should return
`[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]`
with one
`False`
measurement missing.

How can I write this code differently?

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.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download