Ich habe eine Funktion erstellt, die zufällig eine Liste der Buchstaben "a", "b", "c" und "d" generiert. Ich möchte eine neue Liste erstellen, die mit der ersten Liste identisch ist, wobei jedoch alle Buchstaben / Elemente, die mit dem vorherigen Buchstaben / Element identisch sind, entfernt wurden. Wenn ich Probleme habe, beziehe ich mich auf den vorherigen Buchstaben in der Liste.

Zum Beispiel, wenn:

letterlist = ['a','a','a','b','b','a,',b']

Dann sollte die Ausgabe sein,

nondupelist = ['a','b','a','b']

Das Problem ist, dass die Nodupeletterliste mit der Buchstabenliste identisch ist - was bedeutet, dass keine Elemente entfernt werden, die mit der letzten identisch sind -, da die Funktion zum Verweisen auf das vorherige Element in der Buchstabenliste falsch ist. Ich habe versucht, Index und Aufzählung zu verwenden, aber ich verwende sie offensichtlich falsch, weil ich nicht die richtigen Ergebnisse erhalte. Unten ist mein aktueller Versuch.

import random

def rdmlist(letterlist, nodupeletterlist):
    for item in range(20):
        rng = random.random()
        if rng < 0.25:
            letterlist.append("a")
        elif 0.25 <= rng and rng < 0.5:
            letterlist.append("b")
        elif 0.5 <= rng and rng < 0.75:
            letterlist.append("c")
        else:
            letterlist.append("d")
    for letter in letterlist:
        if letter != letterlist[letterlist.index(letter)-1]:
            nodupeletterlist.append(letter)
        else:
            pass
    return

letterlist1 = []
nodupeletterlist1 = []
rdmlist(letterlist1, nodupeletterlist1)

EDIT: Das habe ich letztendlich benutzt. Ich habe diese Lösung einfach verwendet, weil ich verstehe, wie sie funktioniert. Die folgenden Antworten bieten möglicherweise prägnantere oder pythonischere Lösungen.

    for index, letter in enumerate(letterlist, start=0):
        if 0 == index:
            nodupeletterlist.append(letter)
        else:
            pass
    for index, letter in enumerate(letterlist[1:], start = 1):
        if letter != letterlist[index-1]:
            nodupeletterlist.append(letter)
        else:
            pass
0
Darel 24 Feb. 2020 im 08:21

5 Antworten

Beste Antwort

Sie können itertools.groupby verwenden:

import itertools

nodupeletterlist = [k for k, _ in itertools.groupby(letterlist)]

Lösung ohne Verwendung von itertools, wie in den Kommentaren gefordert:

def nodupe(letters):
    if not letters:
        return []
    r = [letters[0]]
    for ch in letters[1:]:
        if ch != r[-1]:
            r.append(ch)
    return r

nodupeletterlist = nodupe(letterlist)

Eine feste Version der vorgeschlagenen "Arbeitslösung":

def nodupe(letters):
    if not letters:
        return []
    r = [letters[0]]
    r += [l for i, l in enumerate(letters[1:]) if l != letters[i]]
    return r

nodupeletterlist = nodupe(letterlist)

Sie können Ihren Zufallsgenerator auch ein wenig vereinfachen, indem Sie {{X0} verwenden }:

import random

chars = 'abcd'
letterlist = random.choices(chars, k=20)

Oder mithilfe von random.randint:

import random

start, end = ord('a'), ord('d')
letterlist = [chr(random.randint(start, end)) for _ in range(20)]
1
Jan Christoph Terasa 24 Feb. 2020 im 07:00
for i, letter in enumerate(([None]+letterlist)[1:], 1):
    if letter != letterlist[i-1]:
        nodupeletterlist.append(letter)
2
Sam Chats 24 Feb. 2020 im 14:19

Das Problem bei der Verwendung von letterlist.index(letter)-1 besteht darin, dass list.index(arg) den Index des ersten Auftretens von arg in list zurückgibt, in diesem Fall den Buchstaben. Dies bedeutet, dass wenn Sie list = ["a", "b", "a"] haben und list.index("a") ausführen, immer 0 zurückgegeben wird. Eine Möglichkeit, das zu tun, was Sie beabsichtigen (aufeinanderfolgende Wiederholungen von Buchstaben zu entfernen), wäre:

nodupeletterlist.append(letterlist[0])
for idx in range(1, len(letterlist)):
    if letterlist[idx] != letterlist[idx-1]:
        nodupeletterlist.append(letterlist[idx])
-1
Andres de Lago 24 Feb. 2020 im 05:38

Mach das:

L1 = ['a','a','a','b','b','c','d']
L2 = []
L2.append(L1[0])
for i in range(1,len(L1)):
    if L1[i] != L1[i-1]:
        L2.append(L1[i])

Set () erstellt eine Menge mit nur eindeutigen Werten, dann konvertiert list () sie wieder in eine Liste mit Werten ohne Wiederholung.

Ich hoffe das hilft...

-2
Aayman Khalid 24 Feb. 2020 im 07:33

Folgendes habe ich mir ausgedacht. Die Verwendung von random.choices() wäre besser als das, was ich unten habe, aber die gleiche Idee. beinhaltet keine itertools

>>> li_1 = [random.choice("abcdefg") for i in range(20)]
>>> li_1
['c', 'e', 'e', 'g', 'b', 'd', 'b', 'g', 'd', 'c', 'e', 'g', 'e', 'c', 'd', 
 'e', 'e', 'f', 'd', 'd']
>>>
>>> li_2 = [li_1[i] for i in range(len(li_1)) 
...                                      if not i or i and li_1[i - 1] != li_1[i]]
>>> li_2
['c', 'e', 'g', 'b', 'd', 'b', 'g', 'd', 'c', 'e', 'g', 'e', 'c', 
 'd', 'e', 'f', 'd']
1
Todd 24 Feb. 2020 im 07:20