簡體   English   中英

Python:list的方法類似於dict.get()

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM