下面是我们的独特功能。它接受参数 l(列表)和 f(函数),返回删除重复项的列表(以相同的顺序)。重复定义为: b 是 a 的重复,当且仅当 f(b) == f(a)。
def uniques(l, f = lambda x: x):
return [x for i, x in enumerate(l) if f(x) not in [f(y) for y in l[:i]]]
我们定义lastTwo如下:
lastTwo = lambda x: x[-2:]
对于您的问题,我们使用如下:
>>> list1
[('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'h', 'i')]
>>> list2
[('b', 'b', 'c'), ('d', 'e', 'a'), ('k', 'h', 'i')]
>>> uniques(list1+list2, lastTwo)
[('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'h', 'i'), ('d', 'e', 'a')]
如果您描述的用例出现很多,您可能需要定义
def hervesMerge(l1, l2):
return uniques(l1+l2, lambda x: x[-2:])
Identity 是我们的默认 f,但它可以是任何东西(只要它是为列表的所有元素定义的,因为它们可以是任何类型)。
f 可以是列表的总和,列表的奇数元素,整数的素数,任何东西。 (请记住,如果它的单射没有意义!通过常数、线性函数等相加将与身份 bc 没有什么不同,它的 f(x) == f(y) w/ x != y 会有所不同)
>>> list1
[(1, 2, 3, 4), (2, 5), (6, 2, 2), (3, 4), (8, 3), (1, 1, 1, 1, 1, 1, 1, 1, 1, 1)]
>>> uniques(list1, sum)
[(1, 2, 3, 4), (2, 5), (8, 3)]
>>> uniques(list1, lambda x: reduce(operator.mul, x)) #product
[(1, 2, 3, 4), (2, 5), (3, 4), (1, 1, 1, 1, 1, 1, 1, 1, 1, 1)]
>>> uniques([1,2,3,4,1,2]) #defaults to identity
[1, 2, 3, 4]
您似乎担心速度,但我的回答确实侧重于短/灵活性,而没有显着(或任何?)速度改进。对于速度很重要的较大列表,您希望利用可散列检查以及已知 list1 和 list2 没有重复项这一事实
>>> s = frozenset(i[-2:] for i in list1)
>>> ans = list(list1) #copy list1
>>> for i in list2:
if i[-2:] not in s: ans.append(i)
>>> ans
[('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'h', 'i'), ('d', 'e', 'a')]
或允许无序
>>> d = dict()
>>> for i in list2 + list1:
d[i[-2:]] = i
>>> d.values()
[('d', 'e', 'f'), ('a', 'b', 'c'), ('g', 'h', 'i'), ('d', 'e', 'a')]
--编辑--
您应该始终能够避免像您在问题中发布的那样的非 Pythonic 循环。这是您更改循环的确切代码:
for k in temp:
u=0
for j in result:
if k[1:3] == j[1:3]:
u=1
break
if u==0:
#if index is None:
result.append([k[0],k[1],k[2]]) // k
result 和 temp 是可迭代的,对于任何可迭代的内容,您都可以将其直接放入 for 循环中而无需 eanges。如果由于某种原因您明确需要索引(不是这种情况,但我上面有一个),您可以使用 enumerate。