匹配列表中的可迭代对象,有很大的困难

Matching up iterables in lists, having significant difficulty

对于个人项目,我有三个列表。其中一个包含一组数组 (l2),其大小始终由设置 l2_size 确定,并且始终包含 l1 的随机成员。另一方面,下一个数组 l3 将始终是一组数量为 len(l1) 的 0。

这意味着...

l1 = [1,2,3,4,5,1,2,3,4,5,1,2,3,4,5]
l2 = [[3, 4, 5, 2, 4],[3, 5, 1, 2, 4], [4, 3, 2, 1, 5]]
l3 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

我需要执行搜索

  1. 从l2[0]开始,如果指针l2[0]命中l2[0],搜索l1找到l1[i] == l2[0]的第一个值。

  2. 一旦l2[0]的第一个值用l3赋给它对应的值。

  3. 由于 l2[0] 中的数组大小为 5 个成员,我们将把相应的值 1 赋给 l3,最多五次。一旦我们达到了那个目标,我们就会进入下一个集合 l2[1]。

  4. 一旦我们完成了 l2[0](以此类推到 l2[1]),我们需要分配下一个相应的值,即 2,不要覆盖 l3 中的值。

插图...

假设这些是棒球计分卡...我的套牌中有 l1 张棒球卡。我手上想要的棒球计分卡的作文在l2里面。这些牌将使我赢得比赛!在这种情况下,l2 = [1,2,3,4,5]。我是个大骗子,必须找到 l1 中的所有 l2(手牌)。在 l1 中查找 l2 我标记他们使用 l3 的位置。我还用 l3 告诉我把它们放在哪只手上。

为了成为一个有效的解决方案,我们必须唯一地配对 l2 中的值,以便使用 l3 将它们唯一地标识为 l1 中的值。这意味着...

l1 = [1,2,3,4,5,1,2,3,4,5]
l2 = [[1,2,3,4,5],[1,2,3,4,5]]
l3 = [1,1,1,1,1,2,2,2,2,2]

会有效。但是...

l1 = [1,2,3,4,5,1,2,3,4,5]
l2 = [[1,2,3,4,5],[1,2,3,4,5]]
l3 = [1,2,1,1,1,2,2,1,2,2]

将无效,因为 l2 中没有任何顺序包含 [2,1,2,4,5] 的手牌。

示例

我们将从 l2[0] 开始遍历 l1 并选取 l2[0] 中的所有对象并将它们签发给 l3。这应该看起来像(手工)...

l1 = [1,2,3,4,5,1,2,3,4,5,1,2,3,4,5]
l2 = [[3, 4, 5, 2, 4],[3, 5, 1, 2, 4], [4, 3, 2, 1, 5]]
l3 = [0,0,1,1,1,0,1,0,1,0,0,0,0,0,0]        

值 1 已分配给 l3,因为这些是我们遇到的相应值的第一个实例。我们现在已经完成了 l2[0],因为我们已经在 l1 中找到了它的所有项目。下一个作业是 l2[1]...

l1 = [1,2,3,4,5,1,2,3,4,5,1,2,3,4,5]
l2 = [[3, 4, 5, 2, 4],[3, 5, 1, 2, 4], [4, 3, 2, 1, 5]]
l3 = [2,2,1,1,1,0,1,0,1,0,0,0,2,2,2]        

这是我编造的但无济于事...

assignvar = 1
pos = 0
for x in l2:
    for y in x:
        for z in l1:
            while userpos < len(l1):
                if y == z:
                    l1[pos] = assignvar
                    while l2_size == pos:
                        assignvar += 1
                        l2_size = l2_size+l2_size #stops pos going out of range, changes assignvar to 2 (so appending the next set of l3 iterables to 2 .etc)
                userpos = userpos+1

真的很困惑如何在我的代码中解决这个问题。我觉得我使用三个 for 循环的想法是正确的,但我已经用我的扳手敲了一段时间了,但我已经完全筋疲力尽了。

真实世界的输入数据集...

l1 = [5005.0, 5002.5, 5003.0, 5003.0, 5003.5, 5002.5, 5003.5, 5004.0, 5004.5, 5004.0, 5002.5, 5005.0, 5004.5, 5004.0, 5005.0, 5002.5, 5003.5, 5004.0, 5002.5, 5002.5, 5004.0, 5004.0, 5003.5, 5001.5, 5001.5, 5005.0, 5003.0, 5005.0, 5003.5, 5000.5, 5002.5, 5003.5, 5005.0]

l2 = [[5002.5, 5004.0], [5002.5, 5004.5], [5002.5, 5004.0], [5002.5, 5005.0], [5002.5, 5004.5], [5002.5, 5004.0], [5002.5, 5005.0], [5002.5, 5004.0], [5002.5, 5004.0], [5002.5, 5004.0], [5002.5, 5005.0], [5002.5, 5005.0], [5002.5, 5005.0], [5003.0, 5003.5], [5003.0, 5003.5], [5003.0, 5004.0], [5003.0, 5004.5], [5003.0, 5004.0], [5003.0, 5005.0], [5003.0, 5004.5], [5003.0, 5004.0], [5003.0, 5005.0], [5003.0, 5003.5], [5003.0, 5004.0], [5003.0, 5004.0], [5003.0, 5004.0], [5003.0, 5003.5], [5003.0, 5005.0], [5003.0, 5005.0], [5003.0, 5003.5], [5003.0, 5003.5], [5003.0, 5005.0], [5003.0, 5003.5], [5003.0, 5003.5], [5003.0, 5004.0], [5003.0, 5004.5], [5003.0, 5004.0], [5003.0, 5005.0], [5003.0, 5004.5], [5003.0, 5004.0], [5003.0, 5005.0], [5003.0, 5003.5], [5003.0, 5004.0], [5003.0, 5004.0], [5003.0, 5004.0], [5003.0, 5003.5], [5003.0, 5005.0], [5003.0, 5005.0], [5003.0, 5003.5], [5003.0, 5003.5], [5003.0, 5005.0], [5002.5, 5004.0], [5002.5, 5004.5], [5002.5, 5004.0], [5002.5, 5005.0], [5002.5, 5004.5], [5002.5, 5004.0], [5002.5, 5005.0], [5002.5, 5004.0], [5002.5, 5004.0], [5002.5, 5004.0], [5002.5, 5005.0], [5002.5, 5005.0], [5002.5, 5005.0], [5002.5, 5005.0], [5002.5, 5004.5], [5002.5, 5004.0], [5002.5, 5005.0], [5002.5, 5004.0], [5002.5, 5004.0], [5002.5, 5004.0], [5002.5, 5005.0], [5002.5, 5005.0], [5002.5, 5005.0], [5002.5, 5004.0], [5002.5, 5004.0], [5002.5, 5004.0], [5002.5, 5005.0], [5002.5, 5005.0], [5002.5, 5005.0], [5002.5, 5004.0], [5002.5, 5004.0], [5002.5, 5005.0], [5002.5, 5005.0], [5002.5, 5005.0], [5002.5, 5004.0], [5002.5, 5004.0], [5002.5, 5005.0], [5002.5, 5005.0], [5002.5, 5005.0], [5001.5, 5005.0], [5001.5, 5005.0], [5001.5, 5005.0], [5001.5, 5005.0], [5001.5, 5005.0], [5001.5, 5005.0], [5003.0, 5005.0], [5003.0, 5003.5], [5003.0, 5003.5], [5003.0, 5005.0], [5002.5, 5005.0]]

l3=[]
for i in range(len(l1)):
    l3.append(int(0))

首先获取子列表,然后使用子列表的元素获取 l1 的索引。根据 l1 的索引为 l3 元素增加 1

l1 = [1,2,3,4,5,1,2,3,4,5,1,2,3,4,5]
l2 = [[3, 4, 5, 2, 4],[3, 5, 1, 2, 4], [4, 3, 2, 1, 5]]
l3 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

def combinList( lst ):
    ''' put list of list together based on index
        for example:
        a = [1,3,5,7]
        b = [2,4,6,8]
        combined list should be [1,2,3,4,5,6,7,8] '''
    step = len(lst)
    res= [None]*len(  reduce(lambda x,y:x+y, lst))
    for i,item in enumerate(lst):
        res[i::step] = sorted(item)
    return res


for value,line in enumerate(l2):
    counter = 0 
    record = {} 
    # count how many time this element appeared 
    for i in line:
        record[ i -1 ] = record.get( i - 1,0) + 1
    newList = combinList( [ [ i for i,j in enumerate(l1) if item == j] for item in line ] )
    for idx in newList:
        # if this element of l3 hasn't been change and there is at least one associated element in l2,put the value to l3 and reduce the number of l2
        if not l3[idx] and record.get(idx%5,0):
            l3[idx] = value + 1
            counter+=1
            record[idx%5] = record[idx%5] -1
        if counter >=5:
            break 
    print l3
print l3

输出:

#first iteration 
[0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
#second iteration 
[2, 1, 1, 1, 1, 0, 2, 2, 1, 2, 0, 0, 0, 2, 0]
#third iteration 
[2, 1, 1, 1, 1, 3, 2, 2, 1, 2, 0, 3, 3, 2, 3]
#final iteration 
[2, 1, 1, 1, 1, 3, 2, 2, 1, 2, 0, 3, 3, 2, 3]

规格仍然有点模糊,但试试这个 - 它适用于 l1 = [1,2,3,4,5,1,2,3,4,5]l2 = [[1,2,3,4,5],[1,2,3,4,5]] 的简单情况。

used_indices = set()

def get_next_index(card, l1 = l1, used_indices = used_indices):
    try:
        # find the next index that has not been used
        index = l1.index(card)
        while index in used_indices:
            # if the index has already been used, find the next one
            index = l1.index(card, index + 1)
    except ValueError as e:
        # this card cannot be found
        print('hand:{}, card:{} not found'.format(hand_no, card))
        index = None
    return index


for hand_no, hand in enumerate(l2, 1):
    for card in hand:
        index = get_next_index(card)
        if index:
            l3[index] = hand_no
            used_indices.add(index)

我通过创建两个称为 "configuration space" 的额外数组来简化解决方案,这些数组被分配布尔值 true(由整数 1 表示),具体取决于已分配给手或子集的成员(一只手)已经分配给一张牌。

此解决方案在 l2 上进行一次旅行,然后在 l1 上进行一次旅行,并且仅当手和卡都未分配时才将卡分配给 l3 中的手(如配置中每个数组中的 0 所示 space).

l1 = [1,2,3,4,5,1,2,3,4,5,1,2,3,4,5] #Total number of players
l2 = [[3, 4, 5, 2, 4],[3, 5, 1, 2, 4], [4, 3, 2, 1, 5]] #Possible teams
l3 = [] #Assigned teams
for i in range(len(l1)):
    l3.append(int(0))
##############################################################################################################################################################
#Configuration space. Responsible for indicating whether (a) a player from l1 has been assigned to a team or (b) a team has already been assigned to a player#
##############################################################################################################################################################

playerbase_configurationspace = []
matchmadeteams_configurationspace = [] #detects if value in l2 has been assigned (if going over a number which has been given value 1 but we need to give it value 2)

for i in range(len(l1)):
    playerbase_configurationspace.append(int(0))
for x in l2:
    for y in x:
        matchmadeteams_configurationspace.append(int(0))


teamsize = len(l2[0])
teamcount = len(l2[0])
assignteam = 1 #Base no. of teams to be assigned


################################
#Flatten list of lists##########
################################

matchmadeteams_processed = []
for x in l2:
    for y in x:
        matchmadeteams_processed.append(y)


####################################################################################################################################
#Teammate handler: makes lookups into the configuration space to help determine whether either a player has been assigned to a team#
####################################################################################################################################

def teammate_handler(isnotfreeplayer,isnotfreeslot, assignteam):

    if playerbase_configurationspace[isnotfreeplayer] == 0 and matchmadeteams_configurationspace[isnotfreeslot] == 0:
        playerbase_configurationspace[isnotfreeplayer] = 1
        matchmadeteams_configurationspace[isnotfreeslot] = 1                                     
        return int(1), assignteam #Outcome 1, safe to add player to empty slot, assign == value to be assigned

    #else either, player is set team, teammate of team is set team (or both):: do nothing
    elif playerbase_configurationspace[isnotfreeplayer] == 1 and matchmadeteams_configurationspace[isnotfreeslot] == 0:
        return int(2) #Outcome 2, continue the for loop iterating through players since the player is not free but the slot is free
    elif playerbase_configurationspace[isnotfreeplayer] == 0 and matchmadeteams_configurationspace[isnotfreeslot] == 1:
        return int(3) #Outcome 3, break the for loop iterating through slots and players since the slot is not free
    elif playerbase_configurationspace[isnotfreeplayer] == 1 and matchmadeteams_configurationspace[isnotfreeslot] == 1:
        return int(4)
    return int(5) #Unexpected error (catch all)

###############################

for teammatepos in enumerate(matchmadeteams_processed):
    print(teamcount)
    if teamcount == 0:
        assignteam += 1
        teamcount = teamsize
    for playerpos in enumerate(l1):
        if playerpos[1] == teammatepos[1]:
            print("Match, using player"+str(playerpos)+" teammate"+str(teammatepos))
            print ()
            print ("Teammate "+str(teammatepos), matchmadeteams_processed)
            print ("Player "+str(playerpos), l1)
            print ("")
            if teammate_handler(playerpos[0], teammatepos[0], assignteam) == (1, assignteam):
                l3[playerpos[0]] = assignteam
                print ("I have assigned teams to this player")
            else:
                continue
        else:
            continue
    teamcount -= 1
print(l3)