簡體   English   中英

如何從一個點迭代列表中的下n個元素

[英]How to iterate over the next n elements in a list from one point

所以我有一個這樣的清單:

my_list = [{"id":21313,"remark":"","marks":"100"}, 
{"id":21314,"remark":"","marks":"29"},
{"id":21315,"remark":"","marks":"15"},
{"id":21316,"remark":"","marks":"50"},
{"id":21317,"remark":"","marks":"20"}]

該列表包含許多元素。 我想做的是遍歷整個列表,以當前元素i作為一個點,從中我們檢查接下來兩個點中該點的標記是多少。 如果說的多於好話,而說的多於不好話。 這是我想要的樣子:

my_list = [{"id":21313,"remark":"good","marks":"100"}, 
{"id":21314,"remark":"bad","marks":"29"},
{"id":21315,"remark":"bad","marks":"15"},
{"id":21316,"remark":"NaN","marks":"50"},
{"id":21317,"remark":"NaN","marks":"20"}]

最后兩個不可用,因為它們后面沒有足夠的條目可進行比較。 有沒有辦法做到這一點?

您可以對滑動窗口迭代器進行稍加修改的版本,其中還包括最后幾個元素:

from itertools import islice

def diminishing_window(seq, n=2):
    """
    (s0, ..., s[n-1]), (s1, ..., sn), ..., (s[-2], s[-1]), (s[-1])
    """
    it = iter(seq)
    result = tuple(islice(it, n))
    if len(result) == n:
        yield result
    for elem in it:
        result = result[1:] + (elem,)
        yield result
    result = result[1:]
    while result:
        yield result
        result = result[1:]

這將使您在數據上的寬度為n “窗口”,直到最后幾個窗口為止,這將逐漸變小。 如果我們認為這些窗口中的第一個項目是“打開”的項目,則可以將其與窗口中的其他項目進行比較以確定其結果。

def dict_replace(d, **kwargs):
    res = d.copy()
    res.update(kwargs)
    return res

def get_remark(a, b):
    if len(b) < 2:
        return "NAN"
    elif all(int(a["marks"]) > int(d["marks"]) for d in b):
        return "good"
    else:
        return "bad"

new_list = [dict_replace(a, remark=get_remark(a, b)) for a, *b in diminishing_window(my_list, 3)]

print(new_list)
# [{'id': 21313, 'remark': 'good', 'marks': '100'}, {'id': 21314, 'remark': 'bad', 'marks': '29'}, 
#  {'id': 21315, 'remark': 'bad', 'marks': '15'}, {'id': 21316, 'remark': 'NAN', 'marks': '50'}, 
#  {'id': 21317, 'remark': 'NAN', 'marks': '20'}]

以當前元素i作為一個點,從中我們檢查接下來兩個點中該點的標記是多還是少。

您可以使用zip_longest使用for循環以3 for一組進行迭代:

from itertools import zip_longest

# dictionary mapping for remark strings
rems = {1: 'good', 0: 'bad'}

for d1, d2, d3 in zip_longest(my_list, my_list[1:], my_list[2:], fillvalue={}):
    if not (d2 and d3):
        d1['remark'] = 'NaN'
    else:
        d1['remark'] = rems[int(d1['marks']) > max(int(d2['marks']), int(d3['marks']))]

print(my_list)

# [{'id': 21313, 'marks': '100', 'remark': 'good'},
#  {'id': 21314, 'marks': '29', 'remark': 'bad'},
#  {'id': 21315, 'marks': '15', 'remark': 'bad'},
#  {'id': 21316, 'marks': '50', 'remark': 'NaN'},
#  {'id': 21317, 'marks': '20', 'remark': 'NaN'}]

順便說一句,您可能希望將這些marks存儲為整數(或浮點數)而不是字符串。 這樣可以避免每次都必須調用int進行比較。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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