-1

I am trying to concise the following simple loop

a = [1,2,3,2,1,5,6,5,5,5]
for x in set(a):
    a.remove(x)

This is working well but I need to know if it is possible to apply the concise for loop like that

a = [x for x in set(a):a.remove(x)]

My desire output is to get or list the duplicates only and get list of them, so the desired output is [1,2,5]

The code is working well

a = [1,2,3,2,1,5,6,5,5,5]

for x in set(a):
    a.remove(x)

print(list(set(a)))

My target is not the code but to concise the loop in the loop. I need to learn this trick.

** Found a simple and effective solution:

print(list(set([x for x in a if a.count(x) > 1])))
YasserKhalil
  • 9,138
  • 7
  • 36
  • 95
  • `set(a)` will remove duplicates. This results in `{1, 2, 5}`. You are going to iterate thru this and remove the values. This results in a subset. Is that what you want? – Joe Ferndz Dec 05 '20 at 04:55
  • I didn't get what you mean (forgive me as I am a beginner). I need to know the structure of using `x for x in ...` . Would I use another variable instead of `a` variable? – YasserKhalil Dec 05 '20 at 04:57
  • 2
    @JoeFerndz It won't delete everything. It will just remove the first occurrence of each one number in the list. – Valerii Boldakov Dec 05 '20 at 04:58
  • @ValeriiBoldakov, you my bad. I edited my comment. Yes, OP is looking to just delete the first occurrences of the value from the set. – Joe Ferndz Dec 05 '20 at 04:59
  • @YasserKhalil, are you trying to remove duplicates? What is your desired output? – Joe Ferndz Dec 05 '20 at 05:00
  • I am seeking to use such line after loop `print(list(set(a)))` to list the duplicates. The problem is not in the code, I need to learn how to concise the loop. – YasserKhalil Dec 05 '20 at 05:01
  • 1
    So you are looking to get `[1, 2, 3, 5, 6]` as the answer? – Joe Ferndz Dec 05 '20 at 05:03
  • @JoeFerndz Yes exactly. – YasserKhalil Dec 05 '20 at 05:03
  • 1
    So you are looking to get the set of a. Why do you need to do list comprehension when python already provides you the option of `set(a)`. If it is for learning purpose, then ok. – Joe Ferndz Dec 05 '20 at 05:08
  • https://stackoverflow.com/questions/23881352/python-list-comprehension-remove-duplicates – Joe Ferndz Dec 05 '20 at 05:13
  • @Steve, totally with you. I think the question is not clear at all. Anyway, I wrote up a list comprehension that gives the result of `list(set(a))` which may be what the ask was. – Joe Ferndz Dec 05 '20 at 05:23
  • @YasserKhalil - Can you PLEASE put the desired result in your question? This is all very confusing the way it is now. It seems that you're saying above in the comments that `[1, 2, 3, 5, 6]` is the right answer. But in the question itself, you seems to say that what you want is the same result given by your `for` loop, which is `[2, 1, 5, 5, 5]`, but just done in a more concise way. So which is it? – CryptoFool Dec 05 '20 at 05:36
  • Question updated. – YasserKhalil Dec 05 '20 at 06:00

3 Answers3

2

Original question

a = a if not all([a.remove(i) for i in set(a) ]) else []
print(a)

As suggested by Copperfield, the following also works:

a = any(a.remove(i) for i in set(a) ) or a

Updated question

from collections import Counter

a = [1,2,3,2,1,5,6,5,5,5]

print([k for k, v in Counter(a).items() if v > 1])
Henry Tjhia
  • 742
  • 1
  • 5
  • 11
  • 1
    you can also use `or` for that: `a = all([a.remove(i) for i in set(a) ]) or a` – Copperfield Dec 05 '20 at 05:20
  • `any` works too, and you don't need to make a temporary list with it: `a = any(a.remove(i) for i in set(a) ) or a` – Copperfield Dec 05 '20 at 05:34
  • Thanks a lot. When I tried your code and tried to print like that `print(set(a))` I got `{1, 2, 5}`. Is it possible to get it as a list `[1, 2, 5]`? – YasserKhalil Dec 05 '20 at 05:51
  • @YasserKhalil You got a ```set``` type because you converted to it in the first place by calling ```set(..)``` constructor. Try print with ```print(a)``` because ```a``` is already a list type. – Henry Tjhia Dec 05 '20 at 05:53
  • Thanks a lot. my target is to get a list of duplicates only. – YasserKhalil Dec 05 '20 at 05:55
  • 1
    @YasserKhalil If you want ```[1, 2, 5]``` as your final output, you can use ```list(...)``` after ```set(...)``` as follows: ```print(list(set(a)))```. – Henry Tjhia Dec 05 '20 at 05:57
  • Yes that is right and I already used it. But what if I need more concise in one line ..? I mean like that `print(list(set([a.remove(x) for x in set(a)])))` – YasserKhalil Dec 05 '20 at 05:58
  • I also found this line that is very simple and effective `print(list(set([x for x in a if a.count(x) > 1])))` – YasserKhalil Dec 05 '20 at 06:18
1

You can just do:

a = [1,2,3,2,1,5,6,5,5,5]
[a.remove(x) for x in set(a)]
print(a)

a will have the same items as after your for loop.

You can read more about list comprehensions.

Valerii Boldakov
  • 1,751
  • 9
  • 19
1

find dups in a list

print ([c for i,c in enumerate(a) if a.count(c) > 1 and i==a.index(c)])

The output of this will be:

[1, 2, 5]

alternate for set(a)

Here's the list comprehension to create the same result as

print(list(set(a)))

This can be achieved by doing the following:

print([c for i,c in enumerate(a) if i==a.index(c)])

Here I am checking if the element c is the first time we encountered (index is i) and if yes, then add to list else ignore.

The output of both these will be:

[1, 2, 3, 5, 6]

While the output is the same, I would strongly recommend using the first method than doing a for loop and checking for index. The cost is too high to do this compared to list(set(a))

Joe Ferndz
  • 8,417
  • 2
  • 13
  • 33