2016-03-31 20 views
1

Wenn ich eine Liste habenPrüfen, ob benachbarten ganzen Zahlen in der Liste gleich sind

a = [9,4,3,6,4,4,3,6,4] 

wie kann ich überprüfen, ob irgendwelche zwei benachbarte Elemente gleich sind? Für das Beispiel würde dies für die Elemente bei Index 4 und 5 gelten (die beide den Wert 4 haben).

+3

Haben Sie eine for-Schleife ausprobiert und überprüfen Sie 'a [i] == a [i + 1]'? –

+0

Ich bekam einen Index außerhalb des Bereichsfehler – boson

+0

Dann sollten Sie 'len (a) - 1' für das Ende des Bereichs verwendet haben. –

Antwort

5
pairs = zip(a, a[1:]) # Create tuples of neighbours 
equals = map(lambda (x, y): x == y, pairs) # List of booleans which tells whether tuple elements are equal or not 
hasEqualNeighbours = any(equals) # Is there a True boolean in the list? 

Oder importieren Sie die eq Funktion und anstelle des Lambda verwenden, und erkennen, dass map können mehrere Listen durchlaufen, so dass Sie nicht zip brauchen:

from operator import eq 
hasEqualNeigbours = any(map(eq, a, a[1:])) 

Sie können auch schlagen auf ein from future_builtins import map wenn Sie auf Python 2 sind. Das macht map einen faulen Iterator, anstatt die gesamte Liste der Paare zu erstellen, spart RAM und vielleicht Laufzeit.

+2

Etwas einfacher zu verwenden 'any' hier, und 'lambda' mit' map' ist immer die schlechteste Option ('map' mit einem C-Builtin kann gut sein, sonst verwenden Sie Generatorausdrücke). In diesem Fall kann 'map' jedoch besser funktionieren, ohne' 'zip'' mit' operator.eq' zu benötigen: 'from operator import eq',' hasEqualNeighbors = any (map (eq, a, a [1:])) '. Wenn man auf Python 2 '' from future_builtins import map' zuerst verwendet, um die generatorbasierte 'map' zu erhalten (so kann' any' frühzeitig raus und es kann vermieden werden, dass es weiter überprüft wird, sobald es auftrifft). – ShadowRanger

+0

Danke, ich wollte nur vermeiden, alles zu importieren, aber Sie sind absolut richtig. Meine Antwort wurde aktualisiert. –

3

Dies ist ein effizienter Weg für Python 3.x in Bezug auf Speicher und Ausführungszeit.

import itertools 
import operator 

if any(map(operator.eq, a, itertools.islice(a, 1, None))): 
    print("There are equal neighbhors") 

itertools.islice() schafft einen Iterator, der eine Sequenz schneidet, ohne eine neue Sequenz zu schaffen. map() prüft dann jedes Mal mit operator.eq(), wenn das Element in der Sequenz und das Element danach gleich sind.
any() dann iteriert über die Karte und gibt zurück, wenn eine True ist.

Für Python 2.x jedoch würde ich dies vorschlagen:

import itertools 
import operator 

if any(itertools.imap(operator.eq, a, itertools.islice(a, 1, None))): 
    print("There are equal neighbhors") 

aufgrund der Tatsache Karte in Python 2.x eine Liste zurückgibt und kein Iterator.

any(len(list(g)) > 1 for k, g in itertools.groupby(a)) 

Der Code ist recht geradlinig, aber itertools den Eingang iterable und brechen sie in Stücke nehmen, wo die Werte gleich sind:

+1

@Christian Hinzugefügt vollständige Erklärung. – Bharel

+0

@mgilson Fertig, danke :-) – Bharel

1

Ich könnte ein itertools.groupby verwenden. Ich schaue nur, ob einer der Chunks mehr als 1 Element hat. Wenn ja, dann haben Sie benachbarte Duplikate.

Dies hat eine obere Grenze/durchschnittliche Zeit Komplexität von O (N), die das Beste ist, was Sie für einen solchen Algorithmus hoffen können. Für einige Eingaben kann es jedoch O (1) sein, da es kurzschließt, sobald es eine Übereinstimmung findet (zum Beispiel Duplikate am Anfang des Iterablen).

0

Ich glaube, dies ist die lesbare Version ist:

>>> from itertools import izip 
>>> any(first == second for first, second in izip(a, a[1:])) 
True 

Die Bewertung der any wird faul sein. Paare werden auf Anforderung von izip erstellt. Wenn Sie Python 3 verwenden, zip bereits tut, was izip tut in Python 2.

Erläuterung:

>>> zip(a, a[1:]) 
[(9, 4), (4, 3), (3, 6), (6, 4), (4, 4), (4, 3), (3, 6), (6, 4)] 

wird Tupeln von Paaren benachbarter Elemente erstellen. any wird ein Generatorausdruck übergeben, um zu überprüfen, ob eines dieser Tupel zwei gleiche Elemente enthält.

Wenn Sie die Speichereffizienz optimieren wollen noch weiter, rufen (i)zip wie folgt aus:

>>> it = iter(a) 
>>> next(it, None) 
9 
>>> zip(a, it) 
[(9, 4), (4, 3), (3, 6), (6, 4), (4, 4), (4, 3), (3, 6), (6, 4)] 

dies vermeiden, wird die Liste a[1:] zu schaffen.

Verwandte Themen