Reputation: 78
I need to create a dictionary of elements without the elements that shows more than once and i want to keep the starting index. Example:
a = ['a', 'b' 'a', 'c']
expected = {'b': 1, 'c': 3}
To solve the problem i tried this way:
def unique_array(foo):
correct, duplicates = {}, set()
for value in foo:
if index, value not in enumerate(correct):
correct[value] = index
else:
duplicates.add(value)
return {k: correct[k] for k in set(correct) - duplicates
There is a better and more efficient way to do this?
Upvotes: 1
Views: 100
Reputation: 1413
you can do this by using a single loop
alphabets = ['a', 'b', 'a', 'c']
alphabetDict = {}
index = 0
for alphabet in alphabets:
count = alphabets.count(alphabet)
if count == 1:
alphabetDict[alphabet] = index
index += 1
else:
index += 1
continue
print(alphabetDict)
Upvotes: -1
Reputation: 1260
One solution is to use a Counter
and two passes. (It's still O(n).)
>>> from collections import Counter
>>> a = ['a', 'b', 'a', 'c']
>>> counts = Counter(a)
>>> {k:idx for idx, k in enumerate(a) if counts[k] == 1}
{'b': 1, 'c': 3}
Upvotes: 3
Reputation: 24232
You have two imbricated loops, which makes the time complexity of your code O(n^2).
An O(n) solution could be:
a = ['a', 'b', 'a', 'c']
out = {}
for index, val in enumerate(a):
if val not in out:
out[val] = index
else:
out[val] = None
out = {item:val for item, val in out.items() if val is not None}
print(out)
# {'b': 1, 'c': 3}
We first create the output, marking the duplicates with the value None
when we encounter them.
At the end, we filter out the keys with None
value. Both operations are O(n).
Upvotes: 1