如何比较字符串与备用lis中元素匹配的2个列表

2024-05-14 00:00:58 发布

您现在位置:Python中文网/ 问答频道 /正文

嗨,我正在学习,所以你可能得忍受我。我有两个列表,我想比较,同时保持任何匹配和附加他们,同时附加任何非匹配到另一个输出列表。 这是我的密码:

def EntryToFieldMatch(Entry, Fields):
    valid = []
    invalid = []
    for c in Entry:
        count = 0
        for s in Fields:
            count +=1
            if s in c:
                valid.append(c)
            elif count == len(Entry):
                invalid.append(s)
                Fields.remove(s)



    print valid
    print "-"*50
    print invalid


def main():
    vEntry = ['27/04/2014', 'Hours = 28', 'Site = Abroad', '03/05/2015', 'Date = 28-04-2015', 'Travel = 2']
    Fields = ['Week_Stop', 'Date', 'Site', 'Hours', 'Travel', 'Week_Start', 'Letters']
    EntryToFieldMatch(vEntry, Fields)

if __name__ = "__main__":
    main()

输出看起来不错,只是没有返回2个输出列表中的所有字段。这是我收到的输出:

['Hours = 28', 'Site = Abroad', 'Date = 28-04-2015', 'Travel = 2']
--------------------------------------------------
['Week_Start', 'Letters']

我只是不知道为什么第二张单子上不包括“周站”。我已经运行了调试器,并按照代码运行了几次,但都没有结果。我读过关于集合的文章,但是我没有找到任何方法来返回匹配的字段,并丢弃不匹配的字段。 我也愿意接受这样的建议:如果有人知道简化整个过程的方法,我不是要免费的代码,只是朝着正确的方向点头。 Python 2.7,谢谢


Tags: infields列表datemaindefcountsite
2条回答

只有两个条件,要么在字符串中,要么计数等于条目的长度,这两个条件都不能捕捉到第一个元素'Week_Stop',长度从7-6-5捕捉Week_Start,但永远不能到达0,所以永远不能到达Week_Stop。你知道吗

如果要保持秩序,更有效的方法是使用集合或collections.OrderedDict

from collections import OrderedDict
def EntryToFieldMatch(Entry, Fields):
    valid = []
    # create orderedDict from the words in Fields
    # dict lookups are 0(1)
    st = OrderedDict.fromkeys(Fields)
    # iterate over Entry
    for word in Entry:
        # split the words once on whitespace
        spl = word.split(None, 1)
        # if the first word/word appears in our dict keys
        if spl[0] in st:
            # add to valid list
            valid.append(word)
            # remove the key
            del st[spl[0]]
    print valid
    print "-"*50
    # only invalid words will be left
    print st.keys()

输出:

['Hours = 28', 'Site = Abroad', 'Date = 28-04-2015', 'Travel = 2']
                         
['Week_Stop', 'Week_Start', 'Letters']    

对于大型列表,这将比二次方法快得多。拥有0(1)dict查找意味着您的代码从二次型变为线性型,每次执行in Fields这是一个0(n)操作。你知道吗

使用set方法类似:

def EntryToFieldMatch(Entry, Fields):
    valid = []
    st = set(Fields)
    for word in Entry:
        spl = word.split(None,1)
        if spl[0] in st:
            valid.append(word)
            st.remove(spl[0])
    print valid
    print "-"*50
    print st

使用集合的区别在于不保持顺序。你知道吗

使用list comprehension

def EntryToFieldMatch(Entries, Fields):

    # using list comprehension 
    # (typically they go on one line, but they can be multiline 
    #  so they look more like their for loop equivalents)
    valid = [entry for entry in Entries
                 if any([field in entry 
                         for field in Fields])]

    invalidEntries = [entry for entry in Entries 
                          if not any([field in entry 
                                      for field in Fields])]

    missedFields = [field for field in Fields
                          if not any([field in entry 
                                      for entry in Entries])]

    print 'valid entries:', valid
    print '-' * 80
    print 'invalid entries:', invalidEntries
    print '-' * 80
    print 'missed fields:', missedFields

vEntry = ['27/04/2014', 'Hours = 28', 'Site = Abroad', '03/05/2015', 'Date = 28-04-2015', 'Travel = 2']
Fields = ['Week_Stop', 'Date', 'Site', 'Hours', 'Travel', 'Week_Start', 'Letters']
EntryToFieldMatch(vEntry, Fields)

valid entries: ['Hours = 28', 'Site = Abroad', 'Date = 28-04-2015', 'Travel = 2']
                                        
invalid entries: ['27/04/2014', '03/05/2015']
                                        
missed fields: ['Week_Stop', 'Week_Start', 'Letters']

相关问题 更多 >