给出字符串列表,如何获取字母变化的索引。例如,对于列表letters = ['A','A','A','A','A','A','A','A','A','A','A','A','B','C','C','D','D','B','B','A','A','A','A'],我们需要找到每个字母变化的开始并生成结果列表,不包括字母'X'。
期望的结果是:
[(11, 'A'), (12, 'B'), (13, 'C'), (16, 'D'), (18, 'B'), (20, 'A')]
- 解决方案
为了解决这个问题,我们提供了几种方法:
方法1:
import itertools
import functools
import operator
letters = ['A','A','A','A','A','A','A','A','A','A','A','A','B','C','C','X','D','X','B','B','A','A','A','A']
groupbysecond = functools.partial(itertools.groupby,key=operator.itemgetter(1))
def transitions(letters):
#segregate transition and non-transition indices
grouped = groupbysecond(enumerate(zip(letters,letters[1:])))
# extract first such entry from each group
firsts = (next(l) for k,l in grouped)
# group those entries together - where multiple, there are first and last
# indices of the run of letters
regrouped = groupbysecond((n,a) for n,(a,b) in firsts)
# special case for first entry, which wants last index of first letter
kfirst,lfirst = next(regrouped)
firstitem = (tuple(lfirst)[-1],) if kfirst != 'X' else ()
#return first item, and first index for all other letters
return itertools.chain(firstitem,(next(l) for k,l in regrouped if k != 'X'))
方法2:
firstChangeFound = False
result = []
for i in range(len(letters)):
if letters[i]!='X' and letters[i]!=letters[i-1]:
if not firstChangeFound:
result.append((i-1, letters[i-1])) #Grab the last occurrence of the first character
result.append((i, letters[i]))
firstChangeFound = True
else:
result.append((i, letters[i]))
方法3:
for i, letter in enumerate(letters[1:], 1):
if letter != 'X' and letters[i] != letters[i-1]:
result.append((i, letter))
first_change = result[0][0]
first_stretch = ''.join(letters[:first_change]).rstrip('X')
if first_stretch:
result.insert(0, (len(first_stretch) - 1, first_stretch[-1]))
方法4:
def find_transitions(letters):
transitions = []
# Iterate over the letters, starting from the second letter.
for i in range(1, len(letters)):
# If the current letter is different from the previous letter and not 'X',
# it's a transition.
if letters[i] != letters[i - 1] and letters[i] != 'X':
# Append the index and the letter to the transitions list.
transitions.append((i, letters[i]))
# If there are any transitions, return the list of transitions.
if transitions:
return transitions
# Otherwise, return an empty list.
else:
return []
方法5:
def find_transitions(letters):
# Create a list to store the transitions.
transitions = []
# Keep track of the current letter and its index.
current_letter = letters[0]
current_index = 0
# Iterate over the letters, starting from the second letter.
for i in range(1, len(letters)):
# If the current letter is different from the previous letter and not 'X',
# it's a transition.
if letters[i] != current_letter and letters[i] != 'X':
# Append the index and the letter to the transitions list.
transitions.append((current_index, current_letter))
# Update the current letter and its index.
current_letter = letters[i]
current_index = i
# Append the index and the letter for the last transition.
transitions.append((current_index, current_letter))
# Return the list of transitions.
return transitions
这些方法都能够找到所需的转换,你可以根据自己的需要选择最合适的一种。