如何创建一个列表,该列表只添加 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']
我创建了一个随机生成字母列表的函数 "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']