5 回答

TA貢獻1784條經(jīng)驗 獲得超2個贊
您可以使用計數(shù)器
>>> from collections import Counter
>>> l = [2, 3, 6, 6, 8, 9, 12, 12, 14]
>>> res = [el for el, cnt in Counter(l).items() if cnt==1]
>>> res
[2, 3, 8, 9, 14]

TA貢獻1831條經(jīng)驗 獲得超10個贊
您始終可以擁有兩套。一個用于檢查是否seen,另一個僅用于保持唯一。set.discard(el)如果存在將刪除。
Inputlist = [2, 3, 6, 6, 8, 9, 12, 12, 14]
seen = set()
ans = set()
for el in Inputlist:
if el not in seen:
seen.add(el)
ans.add(el)
else:
ans.discard(el)
print(list(ans))
編輯:為了咯咯笑,我測量了這兩種解決方案的性能
from timeit import timeit
first = """
def get_from_two_sets():
seen = set()
ans = set()
for el in (2, 3, 6, 6, 8, 9, 12, 12, 14):
if el not in seen:
seen.add(el)
ans.add(el)
else:
ans.discard(el)"""
second = """
def get_from_counter():
return [el for el, cnt in Counter((2, 3, 6, 6, 8, 9, 12, 12, 14)).items() if cnt == 1]
"""
print(timeit(stmt=first, number=10000000))
print(timeit(stmt=second, number=10000000, setup="from collections import Counter"))
產(chǎn)量
0.3130729760000577
0.46127468299982866
太棒了!看來我的解決方案稍微快一些。不要浪費你節(jié)省的納秒!
@abc 解決方案很干凈并且Pythonic,那就去做吧。

TA貢獻1851條經(jīng)驗 獲得超3個贊
一個簡單的列表理解就可以解決問題:
Inputlist = [2, 3, 6, 6, 8, 9, 12, 12, 14]
Outputlist = [item for item in Inputlist if Inputlist.count(item) == 1]

TA貢獻1876條經(jīng)驗 獲得超5個贊
使用集合的另一種解決方案:將輸入列表轉(zhuǎn)換為集合,并從輸入列表中刪除該集合的所有元素。這只會在列表中留下重復(fù)項。現(xiàn)在將其轉(zhuǎn)換為一組,您可以從一組中減去另一組。聽起來很復(fù)雜,但對于短列表來說相當簡短且高效:
l = [2, 3, 6, 6, 8, 9, 12, 12, 14]
inset = set(l)
for i in inset: # <-- usually the element to remove is in the front,
l.remove(i) # <-- but in a worst case, this is slower than O(n)
result = list(inset - set(l))
與簡短示例列表無關(guān)的性能:
# %timeit this solution
1.18 μs ± 1.97 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
# %timeit solution with seen-set
1.23 μs ± 1.49 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
# %timeit solution with Counter class
2.76 μs ± 4.85 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
對于包含 1000 個元素和 10% 重復(fù)項的列表,計數(shù)器解決方案是最快的!

TA貢獻2012條經(jīng)驗 獲得超12個贊
對于僅應(yīng)刪除連續(xù)重復(fù)項的情況的替代解決方案:
from itertools import groupby
inputlist = [2, 3, 6, 6, 8, 9, 12, 12, 14]
outputlist = [x for _, (x, *extra) in groupby(inputlist) if not extra]
這一切所做的就是將相同值的運行組合在一起,將第一個副本解壓到x,其余的輸入list; 我們檢查 said 是否list為空,以確定是否只有一個值,還是多個值,并且只保留單個值的值。
如果您甚至不喜歡臨時的,使用不驗證組的解決方案之一將允許類似的解決方案,但沒有無限制的臨時存儲extra
?list
:ilen
list
outputlist = [x for x, grp in groupby(inputlist) if ilen(grp) == 1]
或者使用一個僅檢查“至少 2”而不迭代超出該點的助手:
def more_than_one(it):
? ? next(it)? # Assumes at least once, which is already the case with groupby groups
? ? try:
? ? ? ? next(it)
? ? except StopIteration:
? ? ? ? return True
? ? return False
outputlist = [x for x, grp in groupby(inputlist) if not more_than_one(grp)]
注意:一般來說,我實際上更喜歡基于abc 的Counter
解決方案,但如果您實際上只想刪除相鄰的重復(fù)項,那么它不足以完成任務(wù)。
添加回答
舉報