Python实现首都字符串特殊大小写转换:连续重复目标字母处理问题咨询
核心问题定位
你得到的输出和预期不符,完全来自两个可直接复现的逻辑漏洞:
- 匹配判断没有统一大小写标准:直接用原始输入的
letter和已经转为全小写的城市名做等值判断,一旦传入大写字母会直接匹配失效 - 对每个独立出现的目标字母,都强制执行前后字符转大写的操作。遇到连续重复的目标字母时,前一个目标字母的处理逻辑会把相邻的第二个目标字母错误转为大写,最终把连续的目标字母块拆成单独处理的单元——比如Brazzaville里连续的两个z,就会被处理成
AzZ,和你想要的AzzA效果完全相反。
修正实现思路
把连续出现的相同目标字母当作一整个连续块处理,不要对块内的每个字母重复做相邻字符转换:
- 统一将传入的参数、城市名全部转成小写做匹配,消除大小写判断误差
- 遍历城市字符时,标记当前是否处于连续目标字母块内
- 只有当遇到连续目标字母块的第一个字符时,才将块前方紧邻的字符转为大写
- 只有当走完整个连续目标字母块、遇到第一个非目标字符时,才将块后方紧邻的字符转为大写
- 块内部的所有目标字母统一保持小写,不做额外转换
- 自动处理边界情况:目标字母在城市名开头/结尾时,不存在对应的前/后邻字符,直接跳过转换避免索引越界
修正后的可运行代码
# 你提供的首都元组定义 capitals = ( 'Kabul', 'Tirana (Tirane)', 'Algiers', 'Andorra la Vella', 'Luanda', "Saint John's", 'Buenos Aires', 'Yerevan', 'Canberra', 'Vienna', 'Baku', 'Nassau', 'Manama', 'Dhaka', 'Bridgetown', 'Minsk', 'Brussels', 'Belmopan', 'Porto Novo', 'Thimphu', 'Sucre', 'Sarajevo', 'Gaborone', 'Brasilia', 'Bandar Seri Begawan', 'Sofia', 'Ouagadougou', 'Gitega', 'Phnom Penh', 'Yaounde', 'Ottawa', 'Praia', 'Bangui', "N'Djamena", 'Santiago', 'Beijing', 'Bogota', 'Moroni', 'Kinshasa', 'Brazzaville', 'San Jose', 'Yamoussoukro', 'Zagreb', 'Havana', 'Nicosia', 'Prague', 'Copenhagen', 'Djibouti', 'Roseau', 'Santo Domingo', 'Dili', 'Quito', 'Cairo', 'San Salvador', 'London', 'Malabo', 'Asmara', 'Tallinn', 'Mbabana', 'Addis Ababa', 'Palikir', 'Suva', 'Helsinki', 'Paris', 'Libreville', 'Banjul', 'Tbilisi', 'Berlin', 'Accra', 'Athens', "Saint George's", 'Guatemala City', 'Conakry', 'Bissau', 'Georgetown', 'Port au Prince', 'Tegucigalpa', 'Budapest', 'Reykjavik', 'New Delhi', 'Jakarta', 'Tehran', 'Baghdad', 'Dublin', 'Jerusalem', 'Rome', 'Kingston', 'Tokyo', 'Amman', 'Nur-Sultan', 'Nairobi', 'Tarawa Atoll', 'Pristina', 'Kuwait City', 'Bishkek', 'Vientiane', 'Riga', 'Beirut', 'Maseru', 'Monrovia', 'Tripoli', 'Vaduz', 'Vilnius', 'Luxembourg', 'Antananarivo', 'Lilongwe', 'Kuala Lumpur', 'Male', 'Bamako', 'Valletta', 'Majuro', 'Nouakchott', 'Port Louis', 'Mexico City', 'Chisinau', 'Monaco', 'Ulaanbaatar', 'Podgorica', 'Rabat', 'Maputo', 'Nay Pyi Taw', 'Windhoek', 'No official capital', 'Kathmandu', 'Amsterdam', 'Wellington', 'Managua', 'Niamey', 'Abuja', 'Pyongyang', 'Skopje', 'Belfast', 'Oslo', 'Muscat', 'Islamabad', 'Melekeok', 'Panama City', 'Port Moresby', 'Asuncion', 'Lima', 'Manila', 'Warsaw', 'Lisbon', 'Doha', 'Bucharest', 'Moscow', 'Kigali', 'Basseterre', 'Castries', 'Kingstown', 'Apia', 'San Marino', 'Sao Tome', 'Riyadh', 'Edinburgh', 'Dakar', 'Belgrade', 'Victoria', 'Freetown', 'Singapore', 'Bratislava', 'Ljubljana', 'Honiara', 'Mogadishu', 'Pretoria, Bloemfontein, Cape Town', 'Seoul', 'Juba', 'Madrid', 'Colombo', 'Khartoum', 'Paramaribo', 'Stockholm', 'Bern', 'Damascus', 'Taipei', 'Dushanbe', 'Dodoma', 'Bangkok', 'Lome', "Nuku'alofa", 'Port of Spain', 'Tunis', 'Ankara', 'Ashgabat', 'Funafuti', 'Kampala', 'Kiev', 'Abu Dhabi', 'London', 'Washington D.C.', 'Montevideo', 'Tashkent', 'Port Vila', 'Vatican City', 'Caracas', 'Hanoi', 'Cardiff', "Sana'a", 'Lusaka', 'Harare') def get_funny_case_capital_cities(letter): target = letter.lower() # 统一转为小写做匹配,消除大小写偏差 result = [] for city in capitals: lower_city = city.lower() if target not in lower_city: continue char_list = list(lower_city) in_target_block = False # 标记是否处于连续目标字母块中 for idx, c in enumerate(char_list): if c == target: # 刚进入连续目标块的起点 if not in_target_block: # 有前邻字符就转大写,避免索引越界 if idx > 0: char_list[idx - 1] = char_list[idx - 1].upper() in_target_block = True # 块内字符保持小写即可 char_list[idx] = char_list[idx].lower() else: # 刚走出连续目标块 if in_target_block: char_list[idx] = char_list[idx].upper() in_target_block = False result_city = "".join(char_list) result.append(result_city) return result print(get_funny_case_capital_cities('z')) # 实际输出:['brAzzAville', 'zAgreb', 'vadUz']
效果验证
- 传入
z参数时,原代码输出的brAzZaville会被修正为brAzzAville - 位于城市开头的Zagreb会被正确处理为
zAgreb - 位于城市结尾的Vaduz会被正确处理为
vadUz - 哪怕出现多连的目标字母(比如连续3个z的测试场景),也只会在连续块的前后两侧做一次大写转换,不会重复修改块内的字符。
内容的提问来源于stack exchange,提问作者patmon1
相关产品推荐
相关产品推荐

