2
\$\begingroup\$

Here is a list where I would like to keep only the 'windows' where there are a group of number higher than 3, but if in any case inside this group you find a smaller number, you keep it.

Moreover, if there is an isolated high number (between zeros for example), we need to delete it.

l = [3.5, 0, 0, 0.5, 4, 10, 20, 3, 20, 10, 2, 0, 0, 3.5, 0, 2, 18, 15, 2, 14, 2, 0]

and the expected result :

[4, 10, 20, 3, 20, 10, 18, 15, 2, 14]

This program does it but I feel this it not very pythonic, could you think of any other way ?

l = [3.5, 0, 0, 0.5, 4, 10, 20, 3, 20, 10, 2, 0, 0, 3.5, 0, 2, 18, 15, 2, 14, 2, 0]
new_l = []
index = []
seuil = 3
for i, elt in enumerate(l):
 if elt > seuil: 
 if (l[i-1] and l[i+1]) > 1: 
 new_l.append(elt)
 index.append(i)
 else:
 pass
 else:
 try: 
 if (l[i-1] and l[i+1]) > seuil: 
 new_l.append(elt)
 index.append(i)
 except IndexError:
 pass
print index
print new_l
asked Jan 6, 2017 at 18:19
\$\endgroup\$
4
  • \$\begingroup\$ Do you actually need the index list? It is not used in the code itself. \$\endgroup\$ Commented Jan 6, 2017 at 18:36
  • \$\begingroup\$ Yes, I need the index list only actually. The new_l is only to check if the process goes well. \$\endgroup\$ Commented Jan 6, 2017 at 18:42
  • \$\begingroup\$ Could you explain in more detail what you mean by a "window", and why the expected result is what you say it should be? I strongly suspect that the code you wrote doesn't actually do what you intend. \$\endgroup\$ Commented Jan 6, 2017 at 21:48
  • \$\begingroup\$ I mean by window that if you have more than 3 following numbers that are higher than the threshold, you keep it. Maybe it's not written the best way but it does what I need. If you have better idea, please share. \$\endgroup\$ Commented Jan 6, 2017 at 23:27

1 Answer 1

3
\$\begingroup\$
  1. Write functions, improvements can range from faster code to the ability to reliably time or profile your code.
  2. You don't need to use else if you're just using pass in that block.
  3. Your code is WET, so it's not DRY. Instead of duplicating the code, you could instead assign to a variable in the if and else, to check against.
  4. You may want to get into a habit of using if __name__ == '__main__':. In short, if you import the file it won't run the code.

This can get you:

def rename_me(l, seuil):
 new_l = []
 index = []
 for i, elt in enumerate(l):
 bound = 1 if elt > seuil else seuil
 try:
 if (l[i-1] and l[i+1]) > bound:
 new_l.append(elt)
 index.append(i)
 except IndexError:
 pass
 return index, new_l

A couple more things:

  • I think you have a bug, (l[i-1] and l[i+1]) > bound probably isn't doing what you think it is. It's only checking if l[i+1] is greater than bound. As 1 and 2 == 2 and 0 and 2 == 0 are both true. Instead you may want to use l[i-1] > bound < l[i+1].
  • I don't see why you'd need the indexes and the elements from the original list, and so you could instead just return one or the other.
  • You can change the function to be a generator function, as this reduces memory usage.
  • You could use a modified itertools.pairwise, to remove the IndexError.
from itertools import tee
def rename_me(l, seuil):
 a, b, c = tee(l, 3)
 next(b, None)
 next(c, None)
 next(c, None)
 for index, (i, j, k) in enumerate(zip(a, b, c), 1):
 if i > (1 if j > seuil else seuil) < k:
 yield index
answered Jan 6, 2017 at 18:48
\$\endgroup\$
2
  • \$\begingroup\$ Ok thanks a lot. One question : what do you call a generator function ? \$\endgroup\$ Commented Jan 6, 2017 at 19:16
  • \$\begingroup\$ @Annabelle I assume you mean how do you call it, to get a list from it you can do list(rename_me(l, seuil)), but it's almost the same as range in Python 3 or xrange in Python 2 \$\endgroup\$ Commented Jan 6, 2017 at 19:18

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.