使用列表理解有条件地连接不均匀的字符串

Joining uneven strings conditionally using list comprehension

我正在使用以下代码来加入 2 个字母的缩写,名字和姓氏 - 这样每 3 个单词就成为一个短语。但是,在某些情况下,名称中包含“Jr”,如下面的字符串示例所示,因此打破了这个原本有效的列表理解。

span = 3
#string sample 
words = words = ['QB', 'Teddy', 'Bridgewater','RB', 'Dalvin', 'Cook', 'WR', 'Keenan', 'Allen', 'TE', 'Dalton', 'Schultz', 'WR', 'Odell', 'Beckham', 'Jr']
item= [" ".join(words[i:i+span]) for i in range(0, len(words), span)]

有没有办法在“Jr.”时有条件地加入 4 的跨度。在这种情况下是第 4 个词吗? 我目前得到的:

['QB Teddy Bridgewater', 'RB Dalvin Cook', 'WR Keenan Allen', 'TE Dalton Schultz', 'WR Odell Beckham', 'Jr']

但预期的输出应该是:

['QB Teddy Bridgewater', 'RB Dalvin Cook', 'WR Keenan Allen', 'TE Dalton Schultz', 'WR Odell Beckham Jr']

假设每个组都以大写缩写开头,您可以将所有字符串连接在一起,在缩写前加上行尾前缀,而其他前缀在 space 前。然后在行尾拆分结果字符串并删除第一个(空)条目。

words = ['QB', 'Teddy', 'Bridgewater','RB', 'Dalvin', 'Cook', 'WR', 'Keenan', 'Allen', 'TE', 'Dalton', 'Schultz', 'WR', 'Odell', 'Beckham', 'Jr']

items = "".join(" \n"[s[:2]==s.upper()]+s for s in words).split("\n")[1:]

print(items)
['QB Teddy Bridgewater', 'RB Dalvin Cook', 'WR Keenan Allen', 'TE Dalton Schultz', 'WR Odell Beckham Jr']

如果缩写列表已知,最好将 [s[:2]==s.upper()] 替换为集合中的成员:[s in {'QB','RB','WR','TE'}](您应该将集合保存在单独的变量中虽然)

如果您不介意使用库,您可以使用正则表达式更简洁地做同样的事情,用行尾替换 spaces:

items = re.sub(r" (?=[A-Z]{2} )","\n"," ".join(words)).split("\n")

这可能有点不可靠,因为任何包含两个字母大写单词的名称都会导致不适当的拆分(例如 ["RB","OJ", "Simpson"])。使用已知的缩写列表,可以通过将它们放在模式中来避免这种情况:

items = re.sub(r" (?=(QB|RB|WR|TE) )","\n"," ".join(words)).split("\n")

一个解决方案可以使用正则表达式:

import re

print(list(re.findall(r"([A-Z]{2}.+?)\s*(?=[A-Z]{2}|\Z)", " ".join(words))))

打印:

['QB Teddy Bridgewater', 'RB Dalvin Cook', 'WR Keenan Allen', 'TE Dalton Schultz', 'WR Odell Beckham Jr']