<p>大致上,您要使用的方法是对字符列表进行两次遍历。在第一个过程中,你会找到每个元音的索引,建立一个要完成的工作列表(要交换的元音的位置)。在</p>
<p>然后通过匹配第一项和最后一项来准备工作列表,直到工作列表中剩下的项目少于两项。(元音的奇数意味着中间的那个不必与任何东西交换)。在</p>
<p>现在只需迭代工作列表、元组/索引对。交换每个对的第一个偏移量处的字符与另一个偏移量处的字符。完成。在</p>
<p>(这是假设您希望将列表转换到位。如果不是,那么您可以从一个副本开始:<code>new_word = word[:]</code>,或者迭代<code>enumerate(word)</code>,并有条件地在每个点附加字符(如果偏移量不在工作列表中)。。。或附加偏移字符(如果此索引与列表中的某个匹配)。在后一种情况下,你可以把你的工作清单改成字典)。在</p>
<p>下面是要演示的代码:</p>
<pre><code>def rev_vowels(word):
word = list(word)
results = word[:]
vowel_locations = [index for index, char in enumerate(word) if char in 'aeiou']
work = zip(vowel_locations[:int(len(vowel_locations)/2)], reversed(vowel_locations))
for left, right in work:
results[left], results[right] = word[right], word[left]
return results
</code></pre>
<p>这确实使用了列表理解、<em>zip()</em>和<em>reversed()</em>内置函数、<em>zip()</em>的第一个参数的复杂切片以及用于交换变量的Python元组打包习惯用法。因此,您可能需要用更详细的构造来替换它们,以满足您的“不需要复杂的内置”约束。在</p>
<p>然而,从根本上讲,列表理解只是围绕着一个<em>for</em>循环的语法糖。因此,总的来说,这演示了在数据上使用两个<em>for</em>循环的方法。当我返回数据的副本作为我的<strong>结果</strong>时,没有这个代码也可以工作。(这就是为什么我在第七行使用元组打包习惯用法(就在<em>return</em>语句之前)。在</p>
<p>如果这个问题是在面试中提出的,我有理由相信这将是一个相当好的答案。您可以很容易地分解如何实现zip,如何将列表理解扩展到传统的<em>for</em>套件(block),并且在返回副本时交换行可以是两个独立的赋值,而不是对数据执行就地转换。在</p>
<p>这些变量名非常冗长。但这是为了让你的意图特别清楚。在</p>