将两个列表对齐并在对齐和未对齐的对象上执行操作。

3

我试图找到一种方法来对齐两个对象列表(按其值排序),通过比较它们的值,在两个列表中都对齐的对象上执行一个操作,如果没有对齐则执行另一个操作。例如,使用姓名和年龄对儿童进行对齐。

为了简单起见,可以尝试只使用两个已排序的整数值列表:

a = (1,2,3,6,7,11,13)
b = (2,3,4,6,7,9)

我希望您能将它们对齐,就像这样:
+----+----+----+----+----+----+----+----+----+
| 01 | 02 | 03 | xx | 06 | 07 | xx | 11 | 13 |
+----+         +----+         +----+----+----+
| xx | 02 | 03 | 04 | 06 | 07 | 09 | xx | xx |
+----+----+----+----+----+----+----+----+----+

要对齐的值执行操作(例如将其附加到列表1中):
list1 = [2,3,6,7]

对于不对齐的值进行操作(例如将其附加到列表2):

list2 = [1,4,9,11,13]

或者只是打印是否对齐的结果:
1 = miss-aligned
2 = aligned
3 = aligned
4 = miss-aligned
6 = aligned
7 = aligned
9 = miss-aligned
11 = miss-aligned
13 = miss-aligned

我尝试了这种方法,但是...
a = (1,2,3,6,7,11,13)
b = (2,3,4,6,7,9)
list1 = []
list2 = []

# find sames and list a different value
for x in a:
    for y in b:
        if x == y:
            list1.append(x)
            print(x," = aligned")
            break
        if y == b[-1]:
            print(x," = miss-aligned")
            list2.append(x)

# find list b different value
for y in b:
    for x in a:
        if x == y:
            break
        if x == a[-1]:
            print(y," = miss-aligned")
            list2.append(y)

print('Same:',list1)
print('Different:',list2)

当我执行操作4和9时,输出结果不符合预期(未按正确顺序执行):

1  = miss-aligned
2  = aligned
3  = aligned
6  = aligned
7  = aligned
11  = miss-aligned
13  = miss-aligned
4  = miss-aligned
9  = miss-aligned
Same: [2, 3, 6, 7]
Different: [1, 11, 13, 4, 9]

我尝试了许多其他方法,但都没有成功。
*编辑:同一列表中没有重复的值。

每个列表中都可能有重复项吗?而且在您的情况下,只有 6 被对齐。您需要更好地定义您所说的“对齐”,也许您的意思是“存在于两个列表中”? - bagrat
定义“对齐”的更好方式是我用 ASCII 绘制的小图。 - Jean-Francois Gallant
很酷,那么请看我的答案。 - bagrat
2个回答

2
由于列表是排序的,你可以像这样操作:
def same_diff(a, b):
    sames = []
    diffs = []
    i = 0
    j = 0
    while i < len(a) and j < len(b):
        if a[i] == b[j]:
            sames.append(a[i])
            i += 1
            j += 1
        elif a[i] > b[j]:
            diffs.append(b[j])
            j += 1
        else:
            diffs.append(a[i])
            i += 1
    diffs += a[i:]
    diffs += b[j:]
    return sames, diffs

a = (1,2,3,6,7,11,13)
b = (2,3,4,6,7,9)

same_diff(a, b)
# ([2, 3, 6, 7], [1, 4, 9, 11, 13])

如果你要对这些值进行操作而不是将剩下的值添加到字符串中,你可以循环处理它们:
def same_diff(a, b):
    sames = []
    diffs = []
    i = 0
    j = 0
    while i < len(a) and j < len(b):
        if a[i] == b[j]:
            print 'aligned', a[i]
            sames.append(a[i])
            i += 1
            j += 1
        elif a[i] > b[j]:
            print 'miss-aligned', b[j]
            diffs.append(b[j])
            j += 1
        else:
            print 'miss-aligned', a[i]
            diffs.append(a[i])
            i += 1
    while i < len(a):
        print 'miss-aligned', a[i]
        diffs.append(a[i])
        i += 1
    while j < len(b):
        print 'miss-aligned', b[j]
        diffs.append(b[j])
        j += 1
    return sames, diffs

会导致:

same_diff(a, b)

miss-aligned 1
aligned 2
aligned 3
miss-aligned 4
aligned 6
aligned 7
miss-aligned 9
miss-aligned 11
miss-aligned 13
# ([2, 3, 6, 7], [1, 4, 9, 11, 13])

这正是我正在寻找的!我已经尝试过类似于你的东西,但是我迷失了方向,很乱,有许多“if条件”,从未得到好的结果。现在我明白了,更清楚了(第二段代码更符合我的要求)。非常感谢! - Jean-Francois Gallant

1
如果您想获取:
  • 两个列表中都存在的元素
  • 只存在于其中一个列表中的元素
那么set会很方便:
a_set = set(a)
b_set = set(b)

same = sorted(a_set.intersection(b_set))
different = sorted(a_set.symmetric_difference(b_set))

print(same)
print(different)

...你将获得:

[2, 3, 6, 7]
[1, 4, 9, 11, 13]

如果对于错位发生在哪个列表并不重要,您可以进行简单的减法运算:
mis_aligned_a = b - a  # [9, 4]
mis_aligned_b = a - b  # [1, 11, 13]

是的,但结果看起来像我写的代码:应用于对齐值的操作顺序良好,但不适用于未对齐的值(末尾的4和9)。而且我不仅想要制作两个相同和不同元素的列表,而是根据是否相同或顺序良好进行操作(例如我所做的“打印”)。 - Jean-Francois Gallant
排序方面怎么样?我有什么遗漏吗? - bagrat
更新了我的答案,请看是否有帮助。 - bagrat
它可以给出良好的结果,但我发现需要更符合我的需求的解决方案。它允许插入代码,无论值是否对齐,就像我所描述的那样。但是非常感谢你帮助我找到解决方案。真的非常感激! - Jean-Francois Gallant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接