【问题标题】:comparing list of tuple elements python比较元组元素列表python
【发布时间】:2015-08-01 21:12:35
【问题描述】:

我有两个元组列表

t1 = [ ('a',3,4), ('b',3,4), ('c',4,5) ]
t2 = [ ('a',4,6), ('c',3,4), ('b',3,6), ('d',4,5) ]

这样

  1. 元组的顺序可能不相同,并且
  2. 列表可能包含不同数量的元组元素。

我的目标是比较两个列表,如果字符串元素匹配,则比较元组中的最后一个整数元素,如果 t1[2]

我尝试了不同的变体,但我遇到的问题是找到一种方法来匹配字符串以进行正确的比较。

return [diff_unique(x[2],y[2]) for x,y in zip(new_list,old_list) ]

其中 diff_unique 进行上述整数比较,new_list 是 t1,old_list 是 t2。

我也试过这个:

return [diff_unique(x[2],y[2]) for x,y in zip(new_list,old_list) if(x[0]==y[0]]

我打算使用返回的列表并创建一个新的四元组列表,其中包含原始 t1 值以及与匹配 t2 元组的差异。即

inc_dec_list = compare_list(new,old)
final_list = [ (f,r,u,chge) for (f,r,u), chge in zip(new,inc_dec_list)]

其中新 = t1 和旧 = t2。这可能是一个重要的细节,抱歉我错过了。

对正确方向有任何帮助吗?

编辑:我添加了我的测试用例程序,该程序模仿了我对那些想要帮助的人的初衷。谢谢大家。

import os 
import sys

old = [('a',10,1),('b',10,2),('c',100,4),('d',200,4),('f',45,2)]
new = [('a',10,2),('c',10,2),('b',100,2),('d',200,6),('e',233,4),('g',45,66)]


def diff_unique(a,b):
    print "a:{} = b:{}".format(a,b)
    if a < b:
        return -1
    elif a==b:
        return 0
    else:
        return 1

def compare_list(new_list, old_list):
    a = { t[0]:t[1:] for t in new_list } 
    b = { t[0]:t[1:] for t in old_list }
    common = list( set(a.keys())&set(b.keys()))
    return [diff_unique(a[key][1], b[key][1]) for key in common]
    #get common tuples
    #common = [x for x,y in zip(new_list,old_list) if x[0] == y[0] ]
    #compare common to old list
    #return [diff_unique(x[2],y[2]) for x,y in zip(new_list,old_list) ]

inc_dec_list = compare_list(new,old)
print inc_dec_list

final_list = [ (f,r,u,chge) for (f,r,u), chge in zip(new,inc_dec_list)]
print final_list

【问题讨论】:

  • 你能添加预期的输出吗?
  • @BhargavRao 我已经编辑了这篇文章。谢谢

标签: python list tuples


【解决方案1】:

要通过不同列表中的字符串匹配元组,您可以使用字典推导(保留元组内的顺序):

a = {t[0]:t[1:] for t in t1} # {'a': (3, 4), 'c': (4, 5), 'b': (3, 4)}
b = {t[0]:t[1:] for t in t1} # {'a': (4, 6), 'c': (3, 4), 'b': (3, 6), 'd': (4, 5)}

然后您可以遍历两个字典的键并进行比较。假设您只想对t1 t2 中存在的键/元组进行比较,您可以使用集合连接键:

common_keys = list(set(a.keys())&set(b.keys()))

最后比较字典的项目并创建您想要的列表,如下所示:

return [diff_unique(a[key][1],b[key][1]) for key in common_keys ]

如果您需要按字母排序的字符顺序输出,请使用按键上的sorted 函数:

return [diff_unique(a[key][1],b[key][1]) for key in sorted(common_keys) ]

如果要考虑所有键,可以执行以下操作:

all_keys = list(set(a.keys()+b.keys()))
l = list()
for key in sorted(all_keys):
    try:
        l.append(diff_unique(a[key][1],b[key][1]))
    except KeyError:
        l.append("whatever you want")
return l

有了关于应该以什么顺序返回什么值的新信息,解决方案是这样的:

ordered_keys = [t[0] for t in t1]
a = {t[0]:t[1:] for t in t1} # {'a': (3, 4), 'c': (4, 5), 'b': (3, 4)}
b = {t[0]:t[1:] for t in t1} # {'a': (4, 6), 'c': (3, 4), 'b': (3, 6), 'd': (4, 5)}
l = list()
for key in sorted(ordered_keys):
    try:
        l.append(diff_unique(a[key][1],b[key][1]))
    except KeyError:
        l.append(0) # default value
return l

【讨论】:

  • 我现在正在测试这个解决方案,它看起来很有希望。结果列表的唯一标准是它与原始(或新列表)的元素平行。
  • 你的意思是列表应该按照t1中元组的顺序排列?你想如何处理一个字符不存在元组的情况?
  • 假设 t1 有 3 个元素,t2 有 5 个。如果 t1 中的所有元素都在 t2 中找到,则结果列表分别返回列表 [1,-1,0]。如果在 t2 中找不到元素,则默认值为 0。因为最后我将列表合并到 t1 final_list = [ (f,r,u,chge) for (f,r,u), chge在 zip(new,inc_dec_list)]
  • 好的。我在底部添加了一个新段落,我认为它可以保持您想要的顺序。
  • 太棒了,准备测试一下。我还添加了模仿我想要完成的测试用例脚本。谢谢
【解决方案2】:

首先,从每个列表构建一个default dictionary,不存在的键的默认值是一个元组,其最后一个元素是用于比较的最小可能值。

SMALL = (-float['inf'],)

from collections import defaultdict
d1 = defaultdict(lambda: SMALL, [(t[0], t[1:]) for t in t1])
d2 = defaultdict(lambda: SMALL, [(t[0], t[1:]) for t in t2])

接下来,遍历每个字典中的键(可以使用itertools.chain 轻松创建)。您可能希望对结果列表的键进行排序以使其具有任何意义(否则,您如何知道哪些键产生了 -1/0/1 中的哪一个?)

from itertools import chain
all_keys = set(chain(d1, d2))
result = [cmp(d1[k][-1], d2[k][-1]) for k in sorted(all_keys)]

【讨论】:

  • 嘿chepner,又是一个很好的答案。然而,一个小建议.. 请添加文档链接,因为它真的会帮助那些不了解 defaultdictchain 的人
【解决方案3】:

这是您问题的简单解决方案, 正如您尝试的那样,它不是一条线。希望对你有帮助

for a in t1:
    for b in t2:
        if a[0] != b[0]:
            continue
        return cmp(a[-1], b[-1])

【讨论】:

  • 此解决方案不会找到所有匹配的元素,如果当前索引不匹配,它只会关闭。但是,如果 b[3] 等于 a[2] 那么我想比较它们。不过谢谢,这是我最初的尝试并注意到了这一点。
【解决方案4】:

python 3.x,你可以比较两个元组列表 ab 因此:

import operator

a = [(1,2),(3,4)]
b = [(3,4),(1,2)]
# convert both lists to sets before calling the eq function
print(operator.eq(set(a),set(b))) #True

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多