【问题标题】:Create a list of tuples from list of tuples从元组列表创建一个元组列表
【发布时间】:2011-12-05 14:39:28
【问题描述】:

我有 4 个列表

l1 = [('x',20),('y',10),('z',40)]
l2 = [('x',30),('r',90),('z',10),('s',20)]
l3 = [('y',20),('z',40),('x',39)]
l4 = [('s',10),('p',20),('z',20)]

从上面的列表中我想得到第五个列表

l_final  = [('x',39),('y',20),('z',40),('r',90),('s',20),('p',20)] 

元组中的所有值都是最大值,即在 l_final 列表中,元组 ('x',39) 39 中的值是 x 相关元组的最大值。

另外,我最多可以解决 2 个列表。但无法为 5 个列表执行此操作。 还为此建议任何其他解决方法。

我在这里添加我的代码最多 2 个列表代码

l1 = [('x',142),('y',523),('r',278),('p',5)]
l2 = [('r',156),('y',663),('s',145),('x',867)]

mylist = []
for i in l1:
    flag = False
    for j in l2:
             if i[0]== j[0]:
                flag = True
                max1 = max(i[1],j[1])
                mylist.append((i[0],max1))
    if flag == False:
        mylist.append((i[0],i[1]))
        flag = True


for i in l2:
    flag = False
    for j in mylist:
        if i[0] == j[0]:
            flag = True
    if flag == False:
         mylist.append((i[0],i[1]))

【问题讨论】:

    标签: python python-3.x


    【解决方案1】:
    l1 = [('x',20),('y',10),('z',40)]
    l2 = [('x',30),('r',90),('z',10),('s',20)]
    l3 = [('y',20),('z',40),('x',39)]
    l4 = [('s',10),('p',20),('z',20)]
    
    d = {}
    for k, v in l1+l2+l3+l4:
        d.setdefault(k, []).append(v)
    
    mylist = [(k, max(v)) for k, v in d.items()]
    

    mylist 现在是:[('p', 20), ('s', 20), ('r', 90), ('y', 20), ('x', 39), ('z', 40)]

    如果您按照给我们的顺序需要它,请更改最后一行:

    mylist = [(k, max(d[k])) for k in 'xyzrsp']
    
    [('x', 39), ('y', 20), ('z', 40), ('r', 90), ('s', 20), ('p', 20)]
    

    【讨论】:

    • 设置输出键顺序的灵活性很好。我也不介意使用setdefault。我觉得很多人都太快联系到collections.defaultdict。不过,我更喜欢我的基本方法。
    【解决方案2】:
    import collections, itertools
    
    class Minimum(object):
        # simulates negative infinity to some degree
        def __cmp__(self, other):
            return -1
    
    def max_elements(*lists): # no idea how to call it
        values = collections.defaultdict(Minimum)
        for key, value in itertools.chain(*lists):
            values[key] = max(values[key], value)
        return values.items()
    
    l1 = [('x',20),('y',10),('z',40)]
    l2 = [('x',30),('r',90),('z',10),('s',20)]
    l3 = [('y',20),('z',40),('x',39)]
    l4 = [('s',10),('p',20),('z',20)]
    
    print max_elements(l1, l2, l3, l4)
    # [('p', 20), ('s', 20), ('r', 90), ('y', 20), ('x', 39), ('z', 40)]
    

    【讨论】:

    • 你可以用一个简单的 lambda 替换 Minimum:values = collections.defaultdict(lambda : -sys.maxint)
    • @PaulMcGuire:不一样。 Python 整数是任意精度的,sys.maxint 只是在不切换机器整数的情况下可以表示的最大值。
    【解决方案3】:

    假设所有数字都是正数

    import collections
    
    l1 = [('x',20),('y',10),('z',40)]
    l2 = [('x',30),('r',90),('z',10),('s',20)]
    l3 = [('y',20),('z',40),('x',39)]
    l4 = [('s',10),('p',20),('z',20)]
    
    d = collections.defaultdict(int)
    
    for k,v in l1 + l2 + l3 + l4:
       if d[k] < v: d[k] = v
    
    result = list(d.iteritems())
    

    result

    [('p', 20), ('s', 20), ('r', 90), ('y', 20), ('x', 39), ('z', 40)]
    

    【讨论】:

    • 请注意,当所有值为负时,这将失败。
    • 是的。我在答案中添加了一个警告。谢谢!
    • 在@CatPlusPlus 的回答中查看我的 lambda 提案。
    【解决方案4】:

    刚刚搞定了。应该做你想做的。尝试添加第 5 个列表并运行它:

    def maxmerge(d1, d2):
        for k in d2.keys():
            if not d1.has_key(k):
                d1[k] = d2[k]
            elif d2[k] > d1[k]:
                d1[k] = d2[k]
    
    def maxtup(*lists):
        r = dict()
        for l in lists:
            maxmerge(r, dict(l))
        return r.items()
    
    l1 = [('x',20),('y',10),('z',40)]
    l2 = [('x',30),('r',90),('z',10),('s',20)]
    l3 = [('y',20),('z',40),('x',39)]
    l4 = [('s',10),('p',20),('z',20)]
    print maxtup(l1,l2,l3,l4)
    

    【讨论】:

      【解决方案5】:

      假设最终列表的顺序无关紧要。

      来自内置 dict 类型的文档:

      dict(seq) -> new dictionary initialized as if via:
          d = {}
          for k, v in seq:
              d[k] = v
      

      因此,如果我们使用多个相等的键进行初始化,seq 中的最后一个将优先。

      我们可以利用这一点,将我们的列表合二为一,按数值的升序对其进行排序,然后构建字典。

      因此,整件事是一个非常短的单行:

      dict(sorted(l1+l2+l3+l4, key=lambda x:x[1])).items()
      

      (或者如果您愿意,可以使用operator.itemgetter 来实现密钥。)

      【讨论】:

      • 不错的技巧,但它的可读性不是很好。序列中的最后一位是实现细节,很可能需要人们阅读 dict 构造函数语义才能理解它。..
      猜你喜欢
      • 2019-03-15
      • 1970-01-01
      • 2013-09-10
      • 2020-10-15
      • 2022-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多