6

I have this list

names = [ ["cat", 9112, "dog123", 5625], ["luck", 1232, "bad23"] ]

According to this question I have done it by using this code

names = [ ["cat", 9112, "dog123", 5625], ["luck", 1232, "bad23"] ]
new = [[x for x in y if isinstance(x, int)] for y in names]

Output -: [[9112, 5625], [1232]]


problem

Now I want to remove duplicate numbers like this.

expected output -: [[912, 562], [123]]

I was using this code but it wasn't working

m = sorted(list(set(new)))
print(m)

Error -:

Traceback (most recent call last):    
   File "main.py", line 13, in <module>     
     m = sorted(list(set(new)))     
TypeError: unhashable type: 'list'

Note -: I want to keep only first original digits.(eg -: 1232 need to become 123 not 132)

1
  • Once you figure that out, all you need to do is remove_dups(x) for x in y if instance(x, int) Commented Dec 23, 2019 at 5:40

6 Answers 6

5

A list is mutable; in Python mutable containers are not hashable. set(names) needs to hash the elements of names to sort them but your names list has list as it's elements (["cat", 9112, "dog123", 5625] and ["luck", 1232, "bad23"]) and hence, it can't be converted to a set.

Try this:

names = [ ["cat", 9112, "dog123", 5625], ["luck", 1232, "bad23"] ]

li = [[x for x in y if isinstance(x, int)] for y in names]
final = [["".join(sorted(set(str(x)), key=str(x).index)) for x in y] for y in li]
print(li)
print(final)

It gives the following output:

[[9112, 5625], [1232]] 
[['912', '562'], ['123']] 

EDIT:

This solution will give the desired result. It may not be best and optimal solution and OP hasn't mentioned anything related to performance.

Sign up to request clarification or add additional context in comments.

5 Comments

Wouldn't sorted(set(str(x)) turn 9112 into 129?
Check my answer again, I am using a different key for sorting! key=str(x).index
I see. In any case, there's more efficient ways to accomplish that without turning numbers into strings stackoverflow.com/questions/25231218/…
Image
key=str(x).index is inefficient, although likely not a big deal for this specific case...
I know. I gave him a quick solution and also mentioned the possibility of further optimization.
1
names = [ ["cat", 9112, "dog123", 5625], ["luck", 1232, "bad23"],["123"] ]
updated_name=[]
for n_list in names:
    undated_n_list=[]
    for n in n_list:
        if type(n)==int:
            new_str = []
            for digit in str(n):
                if digit not in new_str:
                    new_str.append(digit)
            undated_n_list.append(int("".join(map(str, new_str))))
    if undated_n_list:
        updated_name.append(undated_n_list)
print(updated_name)

Output:

[[912, 562], [123]]

It is bit lengthy but hopefully it works for you.

Comments

1

Here's a function to turn integers into ones with unique digits:

def to_uniq_digit_int(n):
      seen = set() # A set that collects seen digits
      result = 0
      for i in str(n): # A lazy way to iterate over digits in an integer
          if i not in seen:
              seen.add(i)
              # Since we are iterating from the most significant to the least significant, we can multiply the result by ten each time to move the integer one digit left
              result = result * 10 + int(i)
      return result

Using a helper function may help with readability of your code.

Comments

1

You can pass individual list to some function that gets the numbers and removes duplicate values

names = [["cat", 9112, "dog123", 5625],["luck", 1232, "bad23"]]
output = [no_duplicate(li) for li in names]

def no_duplicate(li):
    no_str = [no for no in li if type(no)==int] #get the numbers
    newlist = []
    for number in no_str:
        number = list(dict.fromkeys([s for s in str(number)])) #remove duplicate from each number
        number = "".join(x for x in number) 
        newlist.append(int(number)) #append back to the list they belong
    return newlist

output

[[912, 562], [123]]

Hope this helps:)

Comments

1

I feel that the order of digits in integers will not matter if you need to do that. If so You can use set to remove duplicates and then form your integer by single liner:

[[int(''.join(list(set(str(i))))) for i in x] for x in new]

1 Comment

Just checked this answer is very similar to @abhiarora's one..except that I do not use sorted...as I do not think it will be important to the context of the question.
0

The easiest way and understandable to archive this is:

data  = [[9112, 5625], [1232]]

for index, value in enumerate(data):
    for indexY, valueY in enumerate(value):
        data[index][indexY] = int("".join(list(set(valueY.__str__()))))

print(data)

out put:

[[129, 256], [123]]

above code may no be the best result talking about sorted data. but you might find helpful the next chunk of code:

def RemoveDuplicate(numbers):

    result = []

    [result.append(e) for e in str(numbers) if not e in result]

    return int("".join(result))

data  = [[9112, 5625], [1232]]

for index, value in enumerate(data):
    for indexY, valueY in enumerate(value):
        data[index][indexY] = RemoveDuplicate(valueY)

print(data)

out put

[[912, 562], [123]]

in order to reduce lines of code:

result = [[RemoveDuplicate(item) for item in row] for row in data]

print(result)

out put

[[912, 562], [123]]

if you want something more lazy:

result = [[int("".join(list(dict.fromkeys(str(item))))) for item in row] for row in data]

print(result)

out put

[[912, 562], [123]]

How to Remove Duplicates From a Python List

Comments

Your Answer

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.