0
x = (1,1,-13,8,5,0,4,-1,-4)

a = filter(lambda i,j: i == j, x)

print(tuple(a))

I am getting an error instead of the correct answer (1,-13,8,5,0,4,-1,-4). What is my error?

Gyan Veda
  • 6,309
  • 11
  • 41
  • 66
user3398505
  • 607
  • 1
  • 7
  • 13
  • 2
    A `filter` callable is only ever passed *one* argument; what makes you think it would be passed two? – Martijn Pieters Apr 10 '14 at 15:40
  • 6
    And why the arbitrary restriction that a set cannot be used? What is your actual goal here? – Martijn Pieters Apr 10 '14 at 15:40
  • 2
    @MartijnPieters -- Yeah, feels like an [XY problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) to me... – mgilson Apr 10 '14 at 15:42
  • Without any further feedback as to what you actually need, I'm going to assume you wanted to remove duplicates whilst preserving order. – Martijn Pieters Apr 10 '14 at 15:49
  • possible duplicate of [How do you remove duplicates from a list in Python whilst preserving order?](http://stackoverflow.com/questions/480214/how-do-you-remove-duplicates-from-a-list-in-python-whilst-preserving-order) – Martijn Pieters Apr 10 '14 at 15:49

4 Answers4

5
x = (1,1,-13,8,5,0,4,-1,-4)
seen = []
answer = []
for elem in x:
    if elem not in seen:
        seen.append(elem)
        answer.append(elem)
print(tuple(answer))

Ouput:

(1, -13, 8, 5, 0, 4, -1, -4)
inspectorG4dget
  • 110,290
  • 27
  • 149
  • 241
2
x = (1, 1, -13, 8, 5, 0, 4, -1, -4)

print(tuple([item for index, item in enumerate(x) if item not in x[:index]]))

Output:

(1, -13, 8, 5, 0, 4, -1, -4)
Omid Raha
  • 9,862
  • 1
  • 60
  • 64
1

filter will iterate through x and pass each and every element to the lamdba function. But, it will be passing only one element at a time. So, the lambda function cannot accept two elements (unless the last one has a default value).

Apart from that, there are so many solutions without using set. For example, you can use collections.OrderedDict, like this

x = (1, 1, -13, 8, 5, 0, 4, -1, -4)
from collections import OrderedDict
print tuple(OrderedDict.fromkeys(x))
# (1, -13, 8, 5, 0, 4, -1, -4)

if the order of elements doesn't matter, you can use a normal dictionary itself, like this

print tuple({}.fromkeys(x))
# (0, 1, 4, 5, 8, -13, -4, -1)

Or you can use a temporary seen list, like this

x = (1, 1, -13, 8, 5, 0, 4, -1, -4)
seen, result = [], tuple()
for item in x:
    if item not in seen:
        seen.append(item)
        result += (item, )
print result
# (1, -13, 8, 5, 0, 4, -1, -4)
thefourtheye
  • 233,700
  • 52
  • 457
  • 497
0

Assuming you may have duplicates anywhere in the list and not only consecutive repetitions, filter won't help you much.

You can use reduce with a custom function:

reduce(lambda acc, e: acc if e in acc else acc + (e, ), x, ())

Also if you wanted to remove successive repetitions only, it's pretty easy too:

reduce(lambda acc, e: acc if e in acc[-1:] else acc + (e, ), x, ())

Or hand-crafted code

rv = []
for i in x:
    if i not in rv:  # any repetition
    if i not in rv[-1:]  # only successive repetitions
        rv.append(i)
result = tuple(rv)

Just for the kicks, here's are a couple of answers that use filter:

map(lambda i: x[i], filter(lambda i: x[i] not in x[:i], range(len(x)))

[sub[0] for sub in filter(lambda sub: sub[0] != sub[1], [x[i:i+2] for i in range(len(x)-1)])]
Dima Tisnek
  • 11,241
  • 4
  • 68
  • 120