迭代时如何处理python列表中的2个元素(包括删除)

时间:2018-08-28 03:30:56

标签: python algorithm

例如
像m = [[2,3],[3,4],[1,2],[4,7],[1,7]]一样的列表
每个元素都是一个小列表[x,y],x不等于y。
如果m中的元素a和b遵循:a [1] == b [0],则a和b将“合并为” c = [a [0],b [1]],
之后,a和b将从m中删除,
并且c将添加到m中。
当然,m的长度减少了一个。

我的问题是:
经过几次组合操作,
新m中是否存在相同的元素?
如果是,则返回True,否则返回False。 我在下面写一个演示

from random import choice

def combine_two(a,b):
    c = [None,None]
    if a[1]==b[0]:
        c[0]=a[0]
        c[1]=b[1]
    elif b[1] == a[0]:
        c[0]=b[0]
        c[1]=a[1]
    return c

def fusion(list):
    ss = list[:]
    nn = len(ss)
    for i in range(100):
        ele_1 = choice(ss)
        ele_2 = choice(ss)
        c = combine_two(ele_1,ele_2)
        if c != [None,None]:
            ss.remove(ele_1)
            ss.remove(ele_2)
            ss.append(c)
    return ss

def check(list):
    n = len(list)
    for i in range(n):
        for j in range(n):
            if i != j:
                if list[i][0] == list[j][0] and list[i][1] == list[j][1]:
                    return False
    return True

jj = [[2,3],[3,4],[1,2],[4,7],[11,13],[1,7]]
m = fusion(jj)
print m
n = check(m)
print n

但是我的融合功能是一种解决方法。 如果输入列表很长。会出错。
我不知道如何一次智能地处理2个元素。 有没有更好的方法来实现此功能?

1 个答案:

答案 0 :(得分:0)

排序列表的第二个元素因此可以使用二进制搜索,合并后替换一个,但是应该移动另一个。下面的代码:

def combine_two(a ,b):
    c = [None ,None]
    if b[1] == a[0]:
        c[0 ] =b[0]
        c[1 ] =a[1]
    elif a[1] == b[0]:
        c[0 ] =a[0]
        c[1 ] =b[1]
    return c

def binary_find(val, list):
    left = 0
    right = len(list)
    while right - left >= 0:
        mid = (left + right) / 2
        if list[mid][1] > val:
            right = mid - 1
        elif list[mid][1] < val:
            left = mid + 1
        else:
            return mid
    return -1

def fusion_new(list):
    src = list[:]
    src.sort(lambda x, y: x[1] - y[1] if x[1] != y[1] else x[0] - y[0])
    while True:
        i = 0
        merge_num = 0
        while i < len(src):
            elem_1 = src[i]
            ref_val = elem_1[0]

            ##find the match case in src
            index = binary_find(ref_val, src)
            if index >= 0 and index != i:
                elem_2 = src[index]
                c = combine_two(elem_1, elem_2)
                src[i] = c
                src.pop(index)
                merge_num += 1
            else:
                i += 1
        if merge_num < 1:
            break
    return src

def check_new(list):
    temp = list[:]
    temp.sort(lambda x, y: x[0] - y[0] if x[0] != y[0] else x[1] - y[1])
    for i in range(len(temp)-1):
        if temp[i] == temp[i+1]:
            return False
    return True

jj = [[2 ,3] ,[3 ,4] ,[1 ,2] ,[4 ,7] ,[11 ,13] ,[1 ,7]]
m = fusion_new(jj)
print m

n = check_new(m)
print n