【问题标题】:take corresponding values from first list and add to another list in python从第一个列表中获取相应的值并添加到 python 中的另一个列表
【发布时间】:2017-03-18 22:24:28
【问题描述】:

我有两个元组列表如下:

actions = [(2, 1), (1, 0), 'lift 4', (2, 1), 'down 2', (1, 2), 'lift 4', 'down 2']
costs = [(2, 1, 3), (1, 0, 3), (2, 1, 3), (1, 2, 3)]

这是我想要的最终结果:

final_list = [(2, 1, 3), (1, 0, 3),'lift 4', (2, 1, 3),'down 2', (1, 2, 3),'lift 4','down 2' ]

我在这里做什么.. 元组的前两个元素对应于 (x,y) 坐标.. 然后字符串是我在该坐标中采取的“动作”。 现在,在“成本”列表中......基于运动(对角线运动的成本为 3,而线性运动的成本为 2),我将成本附加到元组,忽略动作。

如何合并这两个列表,以便得到“final_list”

【问题讨论】:

  • final_list 被分配了一个无效的 Python 文字。
  • @juanpa.arrivillaga: 抱歉打错了.. 已修复
  • 最好的办法是使用一些中间数据结构将两个列表中的元组按(x,y)进行分组

标签: python


【解决方案1】:

一种解决方案是简单地将costs 视为一个查找表。第一的, 将其转换为方便的dict

cost_dict = {i[:2] : i for i in costs}

{(1, 2): (1, 2, 3), (1, 0): (1, 0, 3), (2, 1): (2, 1, 3)}

然后有条件地转换actions中的值:

final_list = [cost_dict[i] if isinstance(i, tuple) else i for i in actions]

[(2, 1, 3), (1, 0, 3), 'lift 4', (2, 1, 3), 'down 2', (1, 2, 3), 'lift 4', 'down 2']

【讨论】:

  • 如果您在生成最终列表时使用cost_dict.get(i, i),则不需要使用isinstance()
  • @mhawke 好主意。
  • 嗯..这个实现有一个错误..如果两个相同的动作有不同的成本,那么在地图中..最后一个动作的成本会被记录下来..
  • @Fraz 好吧,是的。不过,这听起来确实像 costs 代表一个函数。
【解决方案2】:

相当直接的方法:

costs.reverse()
final_list = []
for action in actions:
    if isinstance(action, tuple):
        # assume that costs in the order as actions
        final_list.append(costs.pop())
    else:
        final_list.append(action)
final_list

【讨论】:

  • 不错的技巧。也可以使用pop(0) 并跳过reverse 步骤。
  • @TomZych,是的,但是pop(0) 的时间复杂度为 O(n)pop() 只是 O(1),所以在我的情况下,算法的整体复杂度只是 O(n) 而不是 pop(0) 的情况下的 O(n^2)。我不确定,在这种情况下性能是否重要(OP 的数组是否足够长),但如果容易做到,则默认情况下更喜欢使用更快的算法。
【解决方案3】:

首先创建一个字典来将动作映射到成本:

actions = [(2, 1), (1, 0), 'lift 4', (2, 1), 'down 2', (1, 2), 'lift 4', 'down 2']
costs = [(2, 1, 3), (1, 0, 3), (2, 1, 3), (1, 2, 3)]
cost_map = {cost[:2] : cost for cost in costs}

现在您可以使用带有默认值的dict.get() 来处理操作列表:

final_list = [cost_map.get(action, action) for action in actions]
>>> final_list
[(2, 1, 3), (1, 0, 3), 'lift 4', (2, 1, 3), 'down 2', (1, 2, 3), 'lift 4', 'down 2']

【讨论】:

    【解决方案4】:

    假设元组actionscosts列表的位置是映射的并且是有序的,为了达到想要的结果你可以创建一个中间列表来存储tuple对象在actions中的索引列举为:

    >>> actions = [(2, 1), (1, 0), 'lift 4', (2, 1), 'down 2', (1, 2), 'lift 4', 'down 2']
    >>> costs = [(2, 1, 3), (1, 0, 3), (2, 1, 3), (1, 2, 3)]
    >>> tuple_position = [i for i, a in enumerate(actions) if isinstance(a, tuple)]
    >>> tuple_position
    [0, 1, 3, 5]
    

    然后根据之前的索引将costs列表中的值更新为actions列表:

    >>> final_list = list(actions)  # copy of `actions` list as you want the desired
                                    # result in the form of new list
    >>> for i, cost in zip(tuple_position, costs):
    ...     final_list[i] = cost
    ...
    >>> final_list
    [(2, 1, 3), (1, 0, 3), 'lift 4', (2, 1, 3), 'down 2', (1, 2, 3), 'lift 4', 'down 2']
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-05
      • 1970-01-01
      • 1970-01-01
      • 2015-04-29
      相关资源
      最近更新 更多