tags:

views:

239

answers:

3

I want to know how to find if there is a certain amount of consecutive numbers in a row in my list e.g.

For example if I am looking for two 1's then:

list = [1, 1, 1, 4, 6] #original list
list = ["true", "true", 1, 4, 6] #after my function has been through the list.

If I am looking for three 1's then:

list = [1, 1, 1, 4, 6] #original list
list = ["true", "true", "true", 4, 6] #after my function has been through the list.

I have tried:

list = [1, 1, 2, 1]

1,1,1 in list #typed into shell, returns "(1, 1, True)"

Any help would be greatly appreciated, I mainly would like to understand whats going on, and how to check if the next element in the list is the same as the first x amount.

+7  A: 

It is a bad idea to assign to list. Use a different name.

To find the largest number of consecutive equal values you can use itertools.groupby

>>> import itertools
>>> l = [1, 1, 1, 4, 6]
>>> max(len(list(v)) for g,v in itertools.groupby(l)) 
3

To search only for consecutive 1s:

>>> max(len(list(v)) for g,v in itertools.groupby(l, lambda x: x == 1) if g) 
3
Mark Byers
ok, that makes sense.But I only want to find out if there are n consecutive 1's right next to each other in the list, not seperated, then I want to change the old list and change those n consecutive 1's to "true" instead of 1.
lost_in_code
A: 

I cannot understand what are you trying to do, but I prepared a quick, and not very good script, but it does what you need.

def repeated(num, lyst):
 # the 'out' list will contain the array you are looking for
 out = []
 # go through the list (notice that you go until "one before
 # the end" because you peek one forward)
 for k in range(len(lyst)-1):
  if lyst[k] == lyst[k+1] == num:
    # if the numbers are equal, add True (as a bool, but you could
    # also pass the actual string "True", as you have it in your question)
    out.append(True)
  else:
   # if they are not the same, add the number itself
    out.append(lyst[k])
 # check the last element: if it is true, we are done (because it was the same as the
 # last one), if not, then we add the last number to the list (because it was not the
 # same)
 if out[-1] != True:
  out.append(lyst[-1])
 # return the list  
 return out

Use it like:

print repeated(1, [1, 1, 1, 4, 6])
Arrieta
This is very close to what I wanted, except for the fact if the list is [1, 1, 1, 1, 2, 3] only the first three 1's become true.I'll see what I can do to correct this.Thanks
lost_in_code
seems that it only changes n-1 1's into True.Since for the last "1" in a line its checking if the next item is the same :Pedit:fixed by adding:elif lyst[k] == lyst[k-1] == num: out.append(True)works a charm
lost_in_code
+1  A: 
>>> def find_repeats(L, num_repeats):
...     idx = 0
...     while idx < len(L):
...         if [L[idx]]*num_repeats == L[idx:idx+num_repeats]:
...             L[idx:idx+num_repeats] = [True]*num_repeats
...             idx += num_repeats
...         else:
...             idx += 1
...     return L
... 
>>> L=[1,1,1,4,6]
>>> print find_repeats(L, 2)
[True, True, 1, 4, 6]
>>> L=[1,1,1,4,6]
>>> print find_repeats(L, 3)
[True, True, True, 4, 6]
>>> 

Here is a version that lets you also specify which number should be matched and stops after the first replacement

>>> def find_repeats(L, required_number, num_repeats, stop_after_match=False):
...     idx = 0
...     while idx < len(L):
...         if [required_number]*num_repeats == L[idx:idx+num_repeats]:
...             L[idx:idx+num_repeats] = [True]*num_repeats
...             idx += num_repeats
...             if stop_after_match:
...                 break
...         else:
...             idx += 1
...     return L
... 
>>> L=[1,1,1,4,6]
>>> print find_repeats(L, 1, 2)
[True, True, 1, 4, 6]
>>> L=[1,1,1,4,6]
>>> print find_repeats(L, 1, 3)
[True, True, True, 4, 6]
>>> L=[1,1,1,4,4,4,6]
>>> print find_repeats(L, 1, 3)
[True, True, True, 4, 4, 4, 6]
>>> L=[1,1,1,4,4,4,6]
>>> print find_repeats(L, 4, 3)
[1, 1, 1, True, True, True, 6]
gnibbler
This is brilliant, even shorter than the other one.How would I make it so it only finds the first set of repeats.e.g. num_repeats = 3L = [1,1,1,2,4,1,1,1]returns [True,True,True,2,4,1,1,1]I've also got it set up so I can search for single numbers at a time. e.g. def(L, required_number, num_repeats)if required_number = 1then it would only change consecutive 1's to Trueif required_number = 4then it would only change consecutive 4's to TrueThanks
lost_in_code
@lost_in_code, sure. I added a new version to my answer
gnibbler
stop_after_match is failing if you try:L=[1,1,4,4,4,1,4,4,4,6]print find_repeats(L, 4, 3)other than that its perfect!
lost_in_code
@lost_in_code, `stop_after_match` is an optional parameter, so use `find_repeats(L, 4, 3, True)` if you wish to enable it.
gnibbler
ahhh thanks, been sitting here for the last hour debugging, wondering what stop_after_match was doing.Thanks
lost_in_code