Python 试图找出在列表中查找连续元素的方法

Python 试图找出在列表中查找连续元素的方法,python,Python,我想做的是:对于列表中两个连续元音的每个实例,第二个元音将变为重音,但前提是前一个元音没有重音。对于Python来说,这仍然是一个新概念,这就是我现在拥有的: sample = ['b' 'e', 'a', 'a', 'e'] vowels = "ae" def accenting(list): vowel_changes = { "a": "á", "e": "é", } for i in range(0, len(list)):

我想做的是:对于列表中两个连续元音的每个实例,第二个元音将变为重音,但前提是前一个元音没有重音。对于Python来说,这仍然是一个新概念,这就是我现在拥有的:

sample = ['b' 'e', 'a', 'a', 'e'] 
vowels = "ae"

def accenting(list):
    vowel_changes = {
        "a": "á",
        "e": "é",
    }
    for i in range(0, len(list)):
        if list[i] in vowels and list[i + 1] in vowels:
            vowel_to_change = list[i + 1]
            for replacement in vowel_changes:
                if replacement in vowel_to_change:
                    vowel_to_change = vowel_to_change.replace(replacement, vowel_changes[replacement])
            print(vowel_to_change)
    return list

print(accenting(sample))

目标是有类似的东西:['b'e','a','e']。现在它返回“á”、“á”和“é”。因此,有两件事我很难弄清楚:1)将替换词放回列表中相应的位置;2)让函数每隔一个元音而不是每一个元音进行更改。我想我可能需要切割并为1创建一个新的列表,可能还有另一个条件为2?不确定。

前瞻可能会很混乱,尤其是在边缘条件下。如果list为零或者最后一个元素不是元音,并且
list[i+1]
从列表末尾消失,该怎么办?另一个选择是在运行时跟踪状态

sample = ['b', 'e', 'a', 'a', 'e'] 

def accenting(sample_list):
    vowel_changes = {
        "a": "á",
        "e": "é",
    }
    was_unaccented_vowel = False
    for i, c  in enumerate(sample_list):
        if c in vowel_changes:
            if was_unaccented_vowel:
                sample_list[i] = vowel_changes[c]
                was_unaccented_vowel = False
            else:
                was_unaccented_vowel = True
        else:
            was_unaccented_vowel = False
    return sample_list 

print(accenting(sample))
该代码更改了原始示例列表。您可以使用
yield
语句将其转换为生成器,并制作一个新副本

sample = ['b', 'e', 'a', 'a', 'e'] 

def accenting(sample_list):
    vowel_changes = {
        "a": "á",
        "e": "é",
    }
    was_unaccented_vowel = False
    for c in sample_list:
        if c in vowel_changes:
            if was_unaccented_vowel:
                c = vowel_changes[c]
                was_unaccented_vowel = False
            else:
                was_unaccented_vowel = True
        else:
            was_unaccented_vowel = False
        yield c

print(list(accenting(sample)))
我还摆弄着一台状态机,尽管我很难宣称它更好

sample = ['b', 'e', 'a', 'a', 'e'] 

vowel_changes = {
    "a": "á",
    "e": "é",
}

def _state_no_accent_check(c):
    if c in vowel_changes:
        return _state_accent_check, c
    else:
        return _state_no_accent_check, c

def _state_accent_check(c):
    return _state_no_accent_check, vowel_changes.get(c, c)

def accenting(sample_list):
    state = _state_no_accent_check
    for c in sample_list:
        state, c = state(c)
        yield c

print(list(accenting(sample)))

此代码有两个问题:

首先也是最重要的一点是,它会引发一个索引器(至少在我使用的Python3.7中是这样),因为在第10行,当您在列表的末尾时,您试图访问列表[I+1],所以您会从列表的末尾掉下来,并引发异常。换句话说,当列表中的最高索引为4时,它尝试访问列表[5],因此它不知道该做什么并崩溃。我建议通过向后看而不是向前看来解决这个问题。我的意思是:与其检查list[I+1]是否是元音,不如检查list[I-1]是否是元音。这样,您就可以从索引1开始,因为索引0无论如何都不能是连续元音。请记住,你必须注意不要连续强调第三个元音;我会让你考虑如何解决这个问题


第二个问题是,你在思考如何替换列表中的字母。你可以简单地说,
list[i]=元音变化[replacement]

这里有一些变化,我们可以让它做你想做的,也可以删除实际上不需要的额外代码行

def accenting(lst): # Use lst instead of list. list is a python reserved keyword.
首先改变循环,这样我们就不会超出列表中的范围。 由于我们正在向前看,我们希望在列表长度之前停止一个,以便我们可以查看下一个

for i in range(0, len(list)-1):
我们需要更改检查lst[i+1]的条件。你让它检查lst[i+1]是否在元音中。但这并不意味着它是连续的。可能是相邻的ae。您已经检查了lst[i]是否在元音中,所以我们可以检查lst[i+1]是否等于元音

然后,if语句可以用另一个语句展开,以覆盖不给倍数加重音的条件

在括号中,我们检查i是否不等于0,这样整个括号就不会计算数组中的第一个字母,因为它前面没有字母。然后我们检查前面的字母是否等于当前字母

if lst[i] in vowels and lst[i+1] == lst[i] and (i != 0 and lst[i-1] != lst[i]):
在if语句内部,我们可以去掉所有变量和第二个循环。因为我们知道lst的位置,我们可以直接分配它。我们还知道要在元音中输入值的键,因此不需要循环

lst[i] = vowels[lst[i]]]
之后,您可以返回列表

sample = ['b', 'e', 'a', 'a', 'e']
vowel_changes = {"a": "á", "e": "é"}

# Start from index 1 and use items (i-1, i) to avoid an IndexError
for i in range(1, len(sample)):
    c, d = sample[i-1], sample[i]
    # Check if the two items are both unaccented vowels
    if all(x in vowel_changes for x in [c, d]):
        # Accent the second vowel
        sample[i] = vowel_changes[d]

print(sample)  # -> ['b', 'e', 'á', 'a', 'é']
总代码如下所示

sample = ['b' 'e', 'a', 'a', 'e'] 
vowels = "ae"

def accenting(lst):
    vowel_changes = {
        "a": "á",
        "e": "é",
    }
    for i in range(0, len(list)-1):
        if lst[i] in vowels and lst[i+1] == lst[i] and (i != 0 and lst[i-1] != lst[i]):
            lst[i] = vowels[lst[i]]]

    return lst

可以使用字典表示所需的字母映射,并使用zip将每个字符与其前一个字符配对。使用列表理解,您可以在一行中获得结果:

mapping  = { ("e","e"):"é", ("a","a"):"á" }

sample   = ['b','e', 'a', 'a', 'e','c','e','e','z'] 
accented = [ {(a,b):b,**mapping}[(a,b)] for a,b in zip([""]+sample,sample) ]

print(accented)
# ['b', 'e', 'a', 'á', 'e', 'c', 'e', 'é', 'z']

下面是一个简单的实现,它改变了列表

sample = ['b', 'e', 'a', 'a', 'e']
vowel_changes = {"a": "á", "e": "é"}

# Start from index 1 and use items (i-1, i) to avoid an IndexError
for i in range(1, len(sample)):
    c, d = sample[i-1], sample[i]
    # Check if the two items are both unaccented vowels
    if all(x in vowel_changes for x in [c, d]):
        # Accent the second vowel
        sample[i] = vowel_changes[d]

print(sample)  # -> ['b', 'e', 'á', 'a', 'é']

如果您想将其放入函数中,可以使用
list.copy()
来避免对输入进行变异。

1)您只需要在列表中为该索引赋值。这有什么难的?2) 修复点1将修复此问题。但是,您发布的代码会为
列表[i+1]
引发一个索引器。你可以用这个问题来解决它。请参阅和以获取建议。另外,您在
示例中缺少一个逗号。顺便说一句
列表
是一个错误的变量名,因为它隐藏了内置项。