我的问题是在列表中找到连续的'3'。例如list('133233313333')
。难以理解的是只有两个相邻的'3'是有效的,三个或更多相邻的'3'不是。因此'33'是有效的,但三重'3'和'3333'无效。我最初尝试了以下内容:
try:
if l[i] == '3' and l[i+1] == '3' and l[i+2] != '3' and l[i-1] != '3':
record_current(i)
except IndexError:
pass
我的意图是忽略比较,如果存在IndexError,它就是真的,但它不起作用。
如果list有一个类似dict.get()的方法,它返回None是一个KeyError,我可以把它写成(l[i+2] == None or l[i+2] != '3')
。
如果我现在必须完成它,我会从其他项目中特别对待第一项和最后两项。但有没有办法优雅地解决这个问题?
答案 0 :(得分:5)
您可以使用itertools.groupby
执行此操作:
>>> from operator import itemgetter
>>> from itertools import groupby
>>> s = list('1332333133334433')
>>> for k, g in groupby(enumerate(s), itemgetter(1)):
if k == '3':
ind = next(g)[0]
if sum(1 for _ in g) == 1:
print ind
...
1
14
答案 1 :(得分:1)
计算连续3秒!
保留一个计数器,每当你遇到一个'3'时,它会递增,并在非'''上复位;比较重置前的2:
j= 0
for i in range(len(L)):
if L[i] == '3':
j+= 1
else:
if j == 2:
print "Found at", i - j
j= 0
if j == 2:
print "Found at", i - j + 1 # Late fix (+ 1)
或者,人们可能会发现'3'和非''3'的连续运行。这样,就可以避免在每个非'3'元素上测试j == 2
,代价是对每个3的序列进行一次额外的循环测试:
i= 0
while i < len(L):
# Find the next '3'
while i < len(L) and L[i] != '3':
i+= 1
j= i
# Find the next non-'3'
while i < len(L) and L[i] == '3':
i+= 1
if i - j == 2:
print "Found at", j
答案 2 :(得分:0)
您正在尝试检查某个语法。为此,您可以实施Deterministic Finite Automaton(或DFA)。
答案 3 :(得分:0)
这是找到两个相同字母的通用解决方案:
def find_two_consecutive(my_str):
prev_letter = None
count = 1
for index, current_letter in enumerate(my_str):
if current_letter == prev_letter:
count += 1
else:
if count == 2:
print("Starting at index: %d" % (index - 2))
count = 1
prev_letter = current_letter
if count == 2:
print("Starting at index: %d" % (index - 2))
答案 4 :(得分:0)
以下是使用正则表达式的解决方案:
import re
m = re.finditer('(?<!3)3{2}(?!3)', '1332333133334433')
for x in m:
print x.span()[0]
正则表达式查找两个连续三个棋子的所有匹配项,只要它们不是后跟或前面的3.输出为:
1
14
您可以在正则表达式中将任何字符替换为“3”,以搜索该字母。
答案 5 :(得分:0)
data = "1332333133334433"
from itertools import groupby
from operator import itemgetter
result = []
for char, grp in groupby(enumerate(data), itemgetter(1)):
groups = list(grp)
if char == "3" and len(groups) == 2:
result.append(groups[0][0])
print result
<强>输出强>
[1, 14]
答案 6 :(得分:0)
如果您的列表实际上只包含一个字母的元素,则应使用re
模块:
import re
chars = list('133233313333433')
numberstr = ''.join(chars)
for match in re.finditer('(?<!3)33(?!3)', numberstr):
print(match.start())
结果:
1
13
模式(?<!3)33(?!3)
表示:找到两个连续的3,既不是前面也不后面是3。
可以找到文档here。
哦,这个:
chars = list('133233313333433')
numberstr = ''.join(chars)
应该只是:
numberstr = '133233313333433'
答案 7 :(得分:0)
如果列表中的“333”
,则返回True
>>> l = "1332333133334433"
>>> any([(i[:3]=='333' and i[3] != '3') for i in map("".join,zip(l[:],l[1:],l[2:],l[3:]))])
True
你可以看到:
>>> map("".join,zip(l[:],l[1:],l[2:],l[3:]))
['1332', '3323', '3233', '2333', '3331', '3313', '3133', '1333', '3333', '3334', '3344', '3443', '4433']