2

I got following task: create a function that will receive as argument a list of different elements and return a list of original elements (count of each element in list should be not more than 1). Order of elements should remain. Like below:

[1, 1.0, '1', -1, 1] # input
[1, 1.0, '1', -1] # output

I tried

def original_list(*a):
    b=[]    
    for i in a:
        if i not in b:
            b.append(i)
return b

but got [1, '1', -1] in return as 1==1.0 is True. So how to force Python to "distinguish" int and float elements of the same value and get correct output list?

Andersson
  • 51,635
  • 17
  • 77
  • 129

3 Answers3

2

If ordering isn't important, just use type and a set comprehension.

input = [1, 1.0, '1', -1, 1]

output = [x[0] for x in {(y, type(y)) for y in input}]

print output

You can use the same idea to preserve ordering.

output = []
output_filter = set()
for y in input:
    if (y, type(y)) not in output_filter:
        output_filter.add((y, type(y)))
        output.append(y)
print output
Pete Cacioppi
  • 880
  • 7
  • 11
  • i figured it was an expanded the answer. – Pete Cacioppi May 27 '15 at 18:12
  • This assumes the list elements are hashable. `input = [[1], [2]]` won't work for example. – Paul Hankin May 28 '15 at 05:34
  • yes, it looks like he is interested in primitives and not data structures. If he tries it on unhashable data structures it will throw an exception (it won't deceptively give a wrong answer, as an `is` based solution would. And I really wanted to steer him away from an O(n^2) solution, to protect him against large data sets. Finally, this whole question isn't terribly Pythonic, so under the circumstances, this seems the best answer. – Pete Cacioppi May 28 '15 at 19:27
1

A little modification to your solution:

def original_list(a):
    b=[]    
    for i in a:
        if i not in b or not isinstance(i,int):
            b.append(i)
    return b
dlavila
  • 1,204
  • 11
  • 25
1

You can also do the following:

>>> example_list = [1, 1.0, '1', -1, 1, 1.0]
>>> output = []
>>> for item in example_list:
        indexes = [i for i, x in enumerate(output) if x==item]
        if not indexes:
            output.append(item)
        elif not filter(lambda index: type(item) == type(output[index]) , indexes):
            output.append(item)
        indexes = []

We have an input list and an output list which is empty initially. First, we iterate on every item of the input list. We calculate the indexes of all the elements in the output list which are equal to that item in the input list.
If the indexes list is empty, we append that item to the output list. Otherwise for every index in the output list, we filter out those indexes for which type of the item and the type of element in output list at that index are same. If the list obtained after filtering is empty, we append the item to output list otherwise item of that type has already been added to the output list.

After the iteration, the output list is our final list.

>>> output
[1, 1.0, '1', -1]

This will preserve both the order and also filter out the duplicates leaving out unique values of different types.

Rahul Gupta
  • 46,769
  • 10
  • 112
  • 126