How Can I Make My Code Be A Set?
Solution 1:
[I'm assuming that you're also user1744238 and user1744316 -- please pick a username and stick to it, that way it's easier to check to see what variants of a question you've asked and what you've already tried.]
One set-based approach is to use two sets as a counter. You only care about whether you've seen something once or more than once. For example, here's an easy-to-explain approach:
- Make an empty set for
once
andmore
. - Loop over every element of your list, and:
- If you haven't seen it before, add it to
once
. - If you've seen it once, remove it from
once
and add it tomore
.
- If you haven't seen it before, add it to
- Now you know what elements you've seen exactly once, in the set
once
. - Loop over the elements of the list, and if you've seen it once, add it to the output list, and remove it from the
once
set so you don't output the same element twice.
This gives me:
In[49]: f([1,4,6,7,3,2,4,5,7,5,6])
Out[49]: [1, 3, 2]
Solution 2:
To clarify, what you want is a set of items that appear once, and only once.
The best option here is to use collections.Counter()
, as it means you only count the items once, rather than once per item, greatly increasing performance:
>>>import collections>>>{key for key, count in collections.Counter(a).items() if count == 1}
{1, 2, 3}
We simply replace the square brackets with curly braces to signify a set comprehension over a list comprehension, to get a set of results.
Solution 3:
If you need to remove any item that is in the list more than once, not just occurences after the first, you can use:
# without using generators / comprehensionsdef only_once(iterable):
seen = set()
duplicates = set()
for item in iterable:
if item in seen:
duplicates.add(item)
seen.add(item)
result = []
for item in iterable:
if item notin duplicates:
result.append(item)
return result
For general order-preserving duplicate elimination, see unique_everseen
in the itertools recipes:
def unique_everseen(iterable, key=None):
"List unique elements, preserving order. Remember all elements ever seen."
# unique_everseen('AAAABBBCCDAABBB') --> A B C D
# unique_everseen('ABBCcAD', str.lower) --> A B C D
seen = set()
seen_add = seen.add
if key is None:
forelementinifilterfalse(seen.__contains__, iterable):
seen_add(element)
yield element
else:
forelementin iterable:
k = key(element)
if k not in seen:
seen_add(k)
yield element
Post a Comment for "How Can I Make My Code Be A Set?"