22 Stimmen

Python: Die Vorkommen in einer Liste gegen einen Wert prüfen

lst = [1,2,3,4,1]

Ich möchte wissen, ob 1 zweimal in dieser Liste vorkommt. Gibt es eine effiziente Möglichkeit, dies zu tun?

47voto

逆さま Punkte 71730

lst.count(1) würde die Anzahl des Auftretens zurückgeben. Wenn Sie die Elemente in einer Liste zählen wollen, erhalten Sie O(n).

Die allgemeine Funktion auf der Liste lautet list.count(x) und gibt die Anzahl der Male zurück, die x in einer Liste vorkommt.

20voto

Katriel Punkte 115208

Fragen Sie, ob jeder Eintrag in der Liste eindeutig ist?

len(set(lst)) == len(lst)

Ob 1 mehr als einmal auftritt?

lst.count(1) > 1

Beachten Sie, dass die obige Methode nicht maximal effizient ist, da sie keinen Kurzschluss verursacht - selbst wenn 1 zweimal vorkommt, werden die restlichen Vorkommnisse trotzdem gezählt. Wenn Sie einen Kurzschluss wünschen, müssen Sie etwas Komplizierteres schreiben.

Ob die erste Element mehr als einmal vorkommt?

lst[0] in lst[1:]

Wie oft kommt jedes Element vor?

import collections
collections.Counter(lst)

Etwas anderes?

4voto

dawg Punkte 89931

Bei mehrfachem Vorkommen erhalten Sie so den Index jedes Vorkommens:

>>> lst=[1,2,3,4,5,1]
>>> tgt=1
>>> found=[]
>>> for index, suspect in enumerate(lst):
...     if(tgt==suspect):
...        found.append(index)
...
>>> print len(found), "found at index:",", ".join(map(str,found))
2 found at index: 0, 5

Wenn Sie die Zählung der einzelnen Elemente in der Liste wünschen:

>>> lst=[1,2,3,4,5,2,2,1,5,5,5,5,6]
>>> count={}
>>> for item in lst:
...     count[item]=lst.count(item)
...
>>> count
{1: 2, 2: 3, 3: 1, 4: 1, 5: 5, 6: 1}

1voto

Hugh Bothwell Punkte 52831
def valCount(lst):
    res = {}
    for v in lst:
        try:
            res[v] += 1
        except KeyError:
            res[v] = 1
    return res

u = [ x for x,y in valCount(lst).iteritems() if y > 1 ]

u ist nun eine Liste aller Werte, die mehr als einmal vorkommen.

Bearbeiten:

@katrielalex: Danke für den Hinweis auf collections.Counter, der mir bisher nicht bekannt war. Es kann auch prägnanter geschrieben werden, indem ein collections.defaultdict verwendet wird, wie in den folgenden Tests gezeigt wird. Alle drei Methoden sind ungefähr O(n) und liegen in der Laufzeitleistung recht nahe beieinander (die Verwendung von collections.defaultdict ist sogar etwas schneller als collections.Counter).

Meine Absicht war es, eine leicht verständliche Antwort auf eine scheinbar relativ einfache Anfrage zu geben. Gibt es denn noch andere Aspekte, die Sie als "schlechten Code" oder "schlecht gemacht" ansehen?

import collections
import random
import time

def test1(lst):
    res = {}
    for v in lst:
        try:
            res[v] += 1
        except KeyError:
            res[v] = 1
    return res

def test2(lst):
    res = collections.defaultdict(lambda: 0)
    for v in lst:
        res[v] += 1
    return res

def test3(lst):
    return collections.Counter(lst)

def rndLst(lstLen):
    r = random.randint
    return [r(0,lstLen) for i in xrange(lstLen)]

def timeFn(fn, *args):
    st = time.clock()
    res = fn(*args)
    return time.clock() - st

def main():
    reps = 5000

    res = []
    tests = [test1, test2, test3]

    for t in xrange(reps):
        lstLen = random.randint(10,50000)
        lst = rndLst(lstLen)
        res.append( [lstLen] + [timeFn(fn, lst) for fn in tests] )

    res.sort()
    return res

Und die Ergebnisse für zufällige Listen mit bis zu 50.000 Einträgen sind wie folgt: (Vertikale Achse: Zeit in Sekunden, horizontale Achse: Anzahl der Elemente in der Liste) alt text

0voto

Jochen Ritzel Punkte 99416

Eine weitere Möglichkeit, alle Elemente zu erhalten, die mehr als einmal vorkommen:

lst = [1,2,3,4,1]
d = {}
for x in lst: 
    d[x] = x in d
print d[1] # True
print d[2] # False
print [x for x in d if d[x]] # [1]

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X