如果我有列表[68,31,93,35,10]
(所有数字都会不同)和列表[93,0,22,10,99,33,21,9]
(同样,所有数字都会不同,但可能与另一个列表重叠),我需要能够准确地获得[68,31,93,35,10,0,22,99,33,21,9]
第二个列表附加到的位置第一个没有重复的列表。我还需要能够准确地获得[68,31,35]
第一个列表在第二个列表中删除了所有重复项的位置。输出的顺序应始终与输入的顺序相同。我该怎么做?(如果它很简单,一个班轮会很好。)
问问题
885 次
6 回答
4
l1 = [68, 31, 93, 35,10]
l2 = [93, 0, 22, 10, 99, 33, 21,9]
l1 + [x for x in l2 if not x in l1]
# [68, 31, 93, 35, 10, 0, 22, 99, 33, 21, 9]
[x for x in l1 if not x in l2]
# [68, 31, 35]
编辑:对于长列表,您不想进行所有这些列表查找。这是另外两个食谱:
联盟:
from collections import OrderedDict
OrderedDict().fromkeys(l1+l2).keys()
# [68, 31, 93, 35, 10, 0, 22, 99, 33, 21, 9]
不同之处:
s = set(l2)
[x for x in l1 if not x in s]
# [68, 31, 35]
于 2011-07-31T13:29:59.373 回答
2
假设输入l1
和l2
,您可以计算它们的有序联合:
l1 + filter(lambda x: x not in l1, l2)
为了得到有序的差 l1 - l2,写
filter(lambda x: x not in l2, l1)
或者,使用列表推导:
>>> l1 = [68,31,93,35,10]
>>> l2 = [93,0,22,10,99,33,21,9]
>>> l1 + [el2 for el2 in l2 if el2 not in l1]
[68, 31, 93, 35, 10, 0, 22, 99, 33, 21, 9]
>>> [el1 for el1 in l1 if el1 not in l2]
[68, 31, 35]
如果您使用非常大的列表(性能是一个问题)执行此操作,请构建一个set
更快的查找:
>>> sl1 = set(s1)
>>> l1 + [el2 for el2 in l2 if el2 not in sl1]
[68, 31, 93, 35, 10, 0, 22, 99, 33, 21, 9]
>>> sl2 = set(s2)
>>> [el1 for el1 in l1 if el1 not in sl2]
[68, 31, 35]
于 2011-07-31T13:29:09.010 回答
0
def unique_chain(*iters):
seen = set()
for it in iters:
for item in it:
if item not in seen:
yield item
seen.add(item)
print list(unique_chain([68, 31, 93, 35,10], [93, 0, 22, 10, 99, 33, 21,9]))
于 2011-07-31T13:33:50.090 回答
0
>>> a = [68,31,93,35,10]
>>> b = [93,0,22,10,99,33,21,9]
>>> result= []
>>> temp = a + b
>>> [result.append(x) for x in temp if x not in result]
>>> result
[68, 31, 93, 35, 10, 0, 22, 99, 33, 21, 9]
>>> a = set(a)
>>> b = set(b)
>>> a - b
set([35, 68, 31])
于 2011-07-31T13:42:44.697 回答
0
也许你可以使用OrderedSet
import collections
class OrderedSet(collections.MutableSet):
def __init__(self, iterable, *args, **kwargs):
super(OrderedSet, self).__init__(*args, **kwargs)
self._data = collections.OrderedDict()
self.update(iterable)
def update(self, iterable):
self._data.update((x, None) for x in iterable)
def __iter__(self):
return iter(self._data)
def __contains__(self, value):
return value in self._data
def __len__(self):
return len(self._data)
def __le__(self, other):
if isinstance(other, OrderedSet):
return self._data <= other._data
return super(OrderedSet, self).__le__(other)
def __and__(self, other):
# Overrided by make the order of self the preferred one
if isinstance(other, collections.Set):
return self._from_iterable(value for value in self
if value in other)
return self & set(other)
def __ior__(self, other):
self.update(other)
return self
def add(self, value):
self._data[value] = None
def discard(self, value):
self._data.pop(value, None)
def __repr__(self):
return "%s(%r)" % (type(self).__name__, self._data.keys())
于 2011-07-31T15:36:31.440 回答
0
在这样定义前两个列表之后,
a = [68,31,93,35,10]
b = [93,0,22,10,99,33,21,9]
这是第一个问题的单行解决方案,
c = [x for x in a+b if x not in set(a).intersection(set(b))]
第二个问题的单线,
d = [x for x in a+b if x not in b]
于 2011-08-01T03:37:51.427 回答