-4

I'm trying to return a recurring set of numbers from a list. I assume I've missed something...

list = range(0,10)
K = (1,4)

def f(x):
    for k in K:
        yield [i for i in x if i <= 1+k or i >= 4+k]       

print filter(f, list)

I hoped that it is possible to set a loop for the definition. But the output is [0, 1, 2, 5, 6, 7, 8, 9] and obviously not the intended [0,1,2,5,8,9].

So how is it possible to separate values?

Alex Essilfie
  • 12,339
  • 9
  • 70
  • 108
  • _"But the output is [0, 1, 2, 5, 6, 7, 8, 9]"_. It is? I'm not getting that. I'm getting `IndentationError: expected an indented block`. Did you post the wrong code? – Kevin Jul 31 '15 at 17:35
  • I'm sure that's just a pasting error. – TigerhawkT3 Jul 31 '15 at 17:35
  • @ Kevin indent the return line – ted Jul 31 '15 at 17:37
  • @TigerhawkT3 you're right, my mistake. – Maaike Jul 31 '15 at 17:44
  • the answer you are looking for is for `K=4` The answer you got is for `(K=4 or K=1)`. It is the union of the results from `K=4` and `K=1` How is that different from what you expect? – ted Jul 31 '15 at 17:44
  • I believe what the OP wants to do is an intersection of the two items obtained when the corrected form of the function `f` is called with the variable `list`. – Alex Essilfie Jul 31 '15 at 18:52

1 Answers1

0

First off, your code needs to be corrected to something like this:

def f(x):
    for k in K:
        yield [i for i in x if i <= 1 + k or i >= 4 + k]

With this correction, list(f(range(0, 10))) produces [[0, 1, 2, 5, 6, 7, 8, 9], [0, 1, 2, 3, 4, 5, 8, 9]].

The next step is to filter for elements that are an intersection both sets. This can be done in a number of ways, as shown in the question Find intersection of two lists?.

Here is my preferred method of doing it, based on this answer:

def intersect(lists):
    count = len(lists)

    if count == 0:
        return []
    elif count == 1:
        return lists
    elif count == 2:
        es1 = set(lists[1])
        return [x for x in lists[0] if x in es1]
    else:
        return intersect((lists[0], intersect(lists[1:])))

Now, using the corrected version of the function you wrote in your question with the intersect function, you get the intended result, as shown below:

result = list(f(range(0, 10)))
result
# [[0, 1, 2, 5, 6, 7, 8, 9], [0, 1, 2, 3, 4, 5, 8, 9]]
intersect(result)
# [0, 1, 2, 5, 8, 9]



WARNING!!

Potential Pitfall:
Python will allow you to give a variable the name of a standard function. Doing this, however, will shadow the function whose name you have taken, making the function hidden and could result in unexpected behaviour. It is therefore recommended that you change the name of your list variable to something else. You can try, for example, l1 or list1.

Community
  • 1
  • 1
Alex Essilfie
  • 12,339
  • 9
  • 70
  • 108
  • @ alex `list(f(range(0, 10)))` produces "TypeError: 'list' object is not callable". `intersect()` is doing just fine. – Prometheus Aug 01 '15 at 17:26
  • @Prometheus: That's because you have a variable called `list`. This variable now overrides the built in function and gives you the error you're reporting. I already explained this potential effect in the warning section of my answer. Refer to it and correct your code after which everything will work alright. – Alex Essilfie Aug 02 '15 at 12:37