问题
Suppose I have a list of lists of elements which are all the same (i'll use int
s in this example)
[range(100)[::4], range(100)[::3], range(100)[::2], range(100)[::1]]
What would be a nice and/or efficient way to take the intersection of these lists (so you would get every element that is in each of the lists)? For the example that would be:
[0, 12, 24, 36, 48, 60, 72, 84, 96]
回答1:
Use sets, which have an intersection method.
>>> s = set()
>>> s.add(4)
>>> s.add(5)
>>> s
set([4, 5])
>>> t = set([2, 4, 9])
>>> s.intersection(t)
set([4])
For your example, something like
>>> data = [range(100)[::4], range(100)[::3], range(100)[::2], range(100)[::1]]
>>> sets = map(set, data)
>>> print set.intersection(*sets)
set([0, 96, 36, 72, 12, 48, 84, 24, 60])
回答2:
I think the built-in set
module should do the trick.
>>> elements = [range(100)[::4], range(100)[::3], range(100)[::2], range(100)[::1]]
>>> sets = map(set, elements)
>>> result = list(reduce(lambda x, y: x & y, sets))
>>> print result
[0, 96, 36, 72, 12, 48, 84, 24, 60]
回答3:
Convert them to sets and use the set.intersection
method, reducing over the list of sets:
xs = [range(100)[::4], range(100)[::3], range(100)[::2], range(100)[::1]]
reduce(set.intersection, [set(x) for x in xs])
reduce
is a functional programming device that iterates through any iterable and applies the function provided to the first two elements, then to the result and the next, and then the result of that and the next, and so on.
回答4:
I'm going to answer my own question:
lists = [range(100)[::4],range(100)[::3],range(100)[::2],range(100)[::1]]
out = set(lists[0])
for l in lists[1:]:
out = set(l).intersection(out)
print out
or
print list(out)
回答5:
l = [range(100)[::4], range(100)[::3], range(100)[::2], range(100)[::1]]
l = [set(i) for i in l]
intersect = l[0].intersection(l[1])
for i in l[2:]:
intersect = intersect.intersection(i)
回答6:
You can treat them as sets and use set.intersection()
:
lists = [range(100)[::4], range(100)[::3], range(100)[::2], range(100)[::1]]
sets = [set(l) for l in lists]
isect = reduce(lambda x,y: x.intersection(y), sets)
回答7:
Here's a one-liner using the good old all()
built-in function:
list(num for num in data[0]
if all(num in range_ for range_ in data[1:]))
Interestingly, this is (I think) more readable and faster than using set
for larger data sets.
来源:https://stackoverflow.com/questions/2893500/take-the-intersection-of-an-arbitrary-number-of-lists-in-python