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

2024-09-30 18:28:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我想做的是:对于列表中两个连续元音的每个实例,第二个元音将变为重音,但前提是前一个元音没有重音。对于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?不确定


Tags: tosamplein列表forifchangelist
3条回答

向前看可能会很混乱,尤其是在边缘条件下。如果列表为零或者最后一个元素不是元音,并且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] = vowel_changes[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'] 
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

相关问题 更多 >