def f5(seq, idfun=None):
# order preserving
if idfun is None:
def idfun(x): return x
seen = {}
result = []
for item in seq:
marker = idfun(item)
# in old Python versions:
# if seen.has_key(marker)
# but in new ones:
if marker in seen: continue
seen[marker] = 1
result.append(item)
return result
def f(seq): # Order preserving
''' Modified version of Dave Kirby solution '''
seen = set()
return [x for x in seq if x not in seen and not seen.add(x)]
好了,现在它是怎么工作的,因为这里有点棘手 if x not in seen and not seen.add(x):
In [1]: 0 not in [1,2,3] and not print('add')
add
Out[1]: True
为什么它返回 True? print (和 set.add)不返回任何值:
In [3]: type(seen.add(10))
Out[3]: <type 'NoneType'>
以及 not None == True,但是:
In [2]: 1 not in [1,2,3] and not print('add')
Out[2]: False
为什么它在[1]中打印“ add”而在[2]中不打印?请参阅 False and print('add'),并且不检查第二个参数,因为它已经知道答案,并且只有当两个参数都为 True 时才返回 True。
更通用、更易读、基于生成器的版本增加了用函数转换值的能力:
def f(seq, idfun=None): # Order preserving
return list(_f(seq, idfun))
def _f(seq, idfun=None):
''' Originally proposed by Andrew Dalke '''
seen = set()
if idfun is None:
for x in seq:
if x not in seen:
seen.add(x)
yield x
else:
for x in seq:
x = idfun(x)
if x not in seen:
seen.add(x)
yield x
没有秩序(它更快) :
def f(seq): # Not order preserving
return list(set(seq))