如何创建一个列表,该列表只添加 python 中相邻索引唯一的字母?

How to create a list which only adds letters that are unique to adjacent indices in python?

我创建了一个随机生成字母列表的函数 "a"、"b"、"c" 和 "d"。我想创建一个与第一个列表相同的新列表,但删除了与之前的 letter/item 相同的任何 letters/items。我遇到问题的地方是指列表中的前一个字母。

例如,如果:

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

那么输出应该是,

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

问题是 nodupeletterlist 与 letterlist 相同 - 这意味着它不会删除与上一个相同的项目 - 因为我得到的函数引用 letterlist 中的前一个项目是错误的。我尝试过使用索引和枚举,但显然我使用错误,因为我没有得到正确的结果。以下是我目前的尝试。

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)

编辑: 这就是我最终使用的。我使用这个解决方案只是因为我了解它是如何工作的。下面的答案可能会提供更简洁或 pythonic 的解决方案。

    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
for i, letter in enumerate(([None]+letterlist)[1:], 1):
    if letter != letterlist[i-1]:
        nodupeletterlist.append(letter)

您使用 letterlist.index(letter)-1 的方式存在问题,list.index(arg) return 是 [=14= 中首次出现 arg 的索引],在这种情况下是字母。这意味着如果你有 list = ["a", "b", "a"] 并且你 运行 list.index("a") 它总是 return 0。 一种做你想做的事情的方法(删除连续重复的字母)是:

nodupeletterlist.append(letterlist[0])
for idx in range(1, len(letterlist)):
    if letterlist[idx] != letterlist[idx-1]:
        nodupeletterlist.append(letterlist[idx])

您可以使用 itertools.groupby:

import itertools

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

不使用 itertools 的解决方案,如评论中所要求:

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)

建议的固定版本"working solution":

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)

您还可以通过使用 random.choices:

稍微简化您的随机生成器
import random

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

或使用 random.randint:

import random

start, end = ord('a'), ord('d')
letterlist = [chr(random.randint(start, end)) for _ in range(20)]

这样做:

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() 将创建一个仅包含唯一值的集合,然后 list() 会将其转换回包含值且没有任何重复的列表。

希望对您有所帮助...

这是我想出的。使用 random.choices() 会比我下面的更好,但想法相同。 不涉及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']