Chcę wziąć dwie listy i znaleźć wartości, które pojawiają się w obu.
a = [1, 2, 3, 4, 5]
b = [9, 8, 7, 6, 5]
returnMatches(a, b)
wróciłby [5]
na przykład.
Chcę wziąć dwie listy i znaleźć wartości, które pojawiają się w obu.
a = [1, 2, 3, 4, 5]
b = [9, 8, 7, 6, 5]
returnMatches(a, b)
wróciłby [5]
na przykład.
Odpowiedzi:
Nie najskuteczniejszy, ale zdecydowanie najbardziej oczywisty sposób to:
>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(a) & set(b)
{5}
jeśli kolejność jest znacząca, możesz to zrobić za pomocą następujących pojęć:
>>> [i for i, j in zip(a, b) if i == j]
[5]
(działa tylko w przypadku list o jednakowej wielkości, co sugeruje znaczenie kolejności).
&
) lub set(a).intersection(b)
będzie tak samo szybkie lub szybsze jak zrozumienie listy.
set(a) & set(b)
?
Użyj set.intersection () , jest szybki i czytelny.
>>> set(a).intersection(b)
set([5])
bool(set(a).intersection(b))
for True
orFalse
difference
lub union
.
.intersection()
vs &
?
Szybki test wydajności pokazujący rozwiązanie Lutza jest najlepszy:
import time
def speed_test(func):
def wrapper(*args, **kwargs):
t1 = time.time()
for x in xrange(5000):
results = func(*args, **kwargs)
t2 = time.time()
print '%s took %0.3f ms' % (func.func_name, (t2-t1)*1000.0)
return results
return wrapper
@speed_test
def compare_bitwise(x, y):
set_x = frozenset(x)
set_y = frozenset(y)
return set_x & set_y
@speed_test
def compare_listcomp(x, y):
return [i for i, j in zip(x, y) if i == j]
@speed_test
def compare_intersect(x, y):
return frozenset(x).intersection(y)
# Comparing short lists
a = [1, 2, 3, 4, 5]
b = [9, 8, 7, 6, 5]
compare_bitwise(a, b)
compare_listcomp(a, b)
compare_intersect(a, b)
# Comparing longer lists
import random
a = random.sample(xrange(100000), 10000)
b = random.sample(xrange(100000), 10000)
compare_bitwise(a, b)
compare_listcomp(a, b)
compare_intersect(a, b)
Oto wyniki na moim komputerze:
# Short list:
compare_bitwise took 10.145 ms
compare_listcomp took 11.157 ms
compare_intersect took 7.461 ms
# Long list:
compare_bitwise took 11203.709 ms
compare_listcomp took 17361.736 ms
compare_intersect took 6833.768 ms
Oczywiście, każdy test sztucznej wydajności powinien być wykonywany z ziarenkiem soli, ale ponieważ set().intersection()
odpowiedź jest co najmniej tak szybka jak inne rozwiązania, a także najbardziej czytelna, powinna być standardowym rozwiązaniem tego powszechnego problemu.
set
z istniejącego list
nie usunie niczego z oryginału list
. Jeśli chcesz, aby specjalna logika obsługiwała duplikaty na liście, myślę, że musisz zadać nowe pytanie, ponieważ odpowiedź będzie musiała być specyficzna dla tego, jak chcesz obsługiwać duplikaty.
Wolę odpowiedzi oparte na zestawie, ale tutaj i tak działa
[x for x in a if x in b]
Najprostszym sposobem na to jest użycie zestawów :
>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(a) & set(b)
set([5])
Szybki sposób:
list(set(a).intersection(set(b)))
>>> s = ['a','b','c']
>>> f = ['a','b','d','c']
>>> ss= set(s)
>>> fs =set(f)
>>> print ss.intersection(fs)
**set(['a', 'c', 'b'])**
>>> print ss.union(fs)
**set(['a', 'c', 'b', 'd'])**
>>> print ss.union(fs) - ss.intersection(fs)
**set(['d'])**
Czy chcesz duplikaty? Jeśli nie, możesz zamiast tego użyć zestawów:
>>> set([1, 2, 3, 4, 5]).intersection(set([9, 8, 7, 6, 5]))
set([5])
innym nieco bardziej funkcjonalnym sposobem sprawdzenia równości listy dla listy 1 (Ist1) i listy 2 (IST2), gdzie obiekty mają głębokość 1 i która zachowuje kolejność, jest:
all(i == j for i, j in zip(lst1, lst2))
a = [1, 2, 3, 4, 5]
b = [9, 8, 7, 6, 5]
lista =set(a)
listb =set(b)
print listb.intersection(lista)
returnMatches = set(['5']) #output
print " ".join(str(return) for return in returnMatches ) # remove the set()
5 #final output
Możesz użyć:
a = [1, 3, 4, 5, 9, 6, 7, 8]
b = [1, 7, 0, 9]
same_values = set(a) & set(b)
print same_values
Wynik:
set([1, 7, 9])
Jeśli chcesz wartość logiczną:
>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(b) == set(a) & set(b) and set(a) == set(a) & set(b)
False
>>> a = [3,1,2]
>>> b = [1,2,3]
>>> set(b) == set(a) & set(b) and set(a) == set(a) & set(b)
True
Poniższe rozwiązanie działa dla dowolnej kolejności elementów listy, a także obsługuje obie listy o różnej długości.
import numpy as np
def getMatches(a, b):
matches = []
unique_a = np.unique(a)
unique_b = np.unique(b)
for a in unique_a:
for b in unique_b:
if a == b:
matches.append(a)
return matches
print(getMatches([1, 2, 3, 4, 5], [9, 8, 7, 6, 5, 9])) # displays [5]
print(getMatches([1, 2, 3], [3, 4, 5, 1])) # displays [1, 3]
np.intersect1d(list1, list2)
you can | for set union and & for set intersection.
for example:
set1={1,2,3}
set2={3,4,5}
print(set1&set2)
output=3
set1={1,2,3}
set2={3,4,5}
print(set1|set2)
output=1,2,3,4,5
curly braces in the answer.
&
operatora na planie jest już odpowiedzią SilentGhost w zaakceptowanej odpowiedzi