[英]Python: list's method similar to dict.get()
我的問題是在列表中找到連續的'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')
。
如果我現在必須完成它,我會從其他項目中特別對待第一項和最后兩項。 但有沒有辦法優雅地解決這個問題?
您可以使用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
算上連續的3s!
保持一個計數器,每當你遇到'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
您正在嘗試檢查某個語法。 為此,您可以實現確定性有限自動機 (或DFA)。
這是找到兩個相同字母的通用解決方案:
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))
這是一個使用正則表達式的解決方案:
import re
m = re.finditer('(?<!3)3{2}(?!3)', '1332333133334433')
for x in m:
print x.span()[0]
正則表達式查找兩個連續三個的所有匹配項,只要它們不是后跟或前面的3.輸出為:
1
14
您可以在正則表達式中將任何字符替換為“3”,以搜索該字母。
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]
如果您的列表實際上只包含一個字母的元素,您應該使用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。
文檔可以在這里找到。
哦,這個:
chars = list('133233313333433')
numberstr = ''.join(chars)
應該只是:
numberstr = '133233313333433'
如果列表中的“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']
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.