【问题标题】:Operate values within a list of lists Python操作列表列表中的值 Python
【发布时间】:2021-09-10 23:03:06
【问题描述】:

我求操作列表如下:

#          key
example = [[2,   2, -10, 'Yes'],
           [2,   8,  21, 'Yes'],
           [2,  19,  14, 'Non'],
           [2,  30, -22, 'Non'],
           [4, -15,  31, 'Yes'],
           [4,   2,  17, 'Yes'],
           [4,   3, -90, 'Non']]


# What I have tried through dictionaries 
dictsum = dict()
for i in example:
    if i[0] in dictsum.keys():
        if i[3] == "Yes":
            dictsum[i[0]][0] = dictsum[i[0]][0]+i[1]
            dictsum[i[0]][1] = dictsum[i[0]][1]+i[2]
    else:
        dictsum[i[0]] = [i[1], i[2]]
        
onlysum = [[k,v[0], v[1]] for k,v in dictsum.items()]        

如前所述,所有行 'i[1]' 和 'i[2]' 都已添加,尊重它们的键 'i[0]' 和条件 'i[3]'。

如果 i[3] == "Non" 则我尝试找到离零最远的值,并根据其对应的键 'i[0]' 添加该值

应该是这样的:

result = [[2,   10 + 30,   11 +(-22)], 
          [4,   -13 + 3,   48 +(-90)]]

# Finally
result = [[2, 40, -11], 
          [4, -10, -42]]

我澄清一下,这是我自己提出的一个示例,以了解在这些情况下如何操作列表,我不是专家。如果有人知道如何为您提供解决方案和反馈,我很感激您的分享,亲切的问候。

【问题讨论】:

  • 如果你有 [2, 19, -22, "Non"][2, 30, 14, "Non"]。哪一个被认为是“离零最远”?
  • 那么,对于每个键 i[0],您想要(所有“是”元素和最多一个“非”元素)的[i[1], i[2]] 的坐标总和?鉴于至少有 2 个坐标可能,您指的是哪个“值”离零最远?这是一个离零最远的绝对值吗?你如何在 -1 和 1 之间进行决胜局?
  • 解决方案是 [2, 30, -22] 因为我尝试做的是对于每个密码,在这种情况下 (2),我得到的值离零最远。 @not_speshal
  • 离零最远的值是,如果我们有 -1 和 1,那么在这种情况下它将是正值。非常好的问题,非常感谢。 @kcsquared
  • 我坚持使用正整数 [2, 20, 20, "no"],非常好的问题,谢谢。 @not_speshal

标签: python python-3.x list dictionary


【解决方案1】:
  1. 首先收集所有“是”值的总和:
dictsum = {i[0]: [sum(x[1] for x in example if x[0]==i[0] and x[-1]=="Yes"), 
                  sum(x[2] for x in example if x[0]==i[0] and x[-1]=="Yes")] for i in example}
>>> dictsum
{2: [10, 11], 4: [-13, 48]}
  1. 使用 max 和所需的 key 函数更新每个键的第 0 和第 1 个列表元素:
output = {k: [v[0]+max([l[1] for l in example if l[0]==k and l[-1]=="Non"], key=abs), \
              v[1]+max([l[2] for l in example if l[0]==k and l[-1]=="Non"], key=abs)] \
          for k,v in dictsum.items()}

>>> output
{2: [40, -11], 4: [-10, -42]}

【讨论】:

  • 不知道是不是同一个按键功能;显然 max(-1, 1) 应该是 1。但是,运行 max([-1, 1], key=abs) 会给出 -1。我相信 Python 在 tie 的情况下会选择第一个值。
  • 正确@kcsquared
  • 非常感谢您的贡献,通过字典和压缩列表操作的主题并没有很好地主导它,但我会继续研究您的程序逻辑。亲切的问候。 @not_speshal
【解决方案2】:

你可以这样做:

dictsum = collections.defaultdict(lambda: [0, 0])
max_non_values = collections.defaultdict(lambda: [0, 0])

def special_max(x, y):
    if abs(x) < abs(y):
        return y
    elif abs(x) > abs(y):
        return x
    else:
        return max(x, y)


for key, val_1, val_2, include in example:
    if include == "Yes":
        dictsum[key][0] = dictsum[key][0] + val_1
        dictsum[key][1] = dictsum[key][1] + val_2
    else:
        max_non_values[key][0] = special_max(max_non_values[key][0], val_1)
        max_non_values[key][1] = special_max(max_non_values[key][1], val_2)

onlysum = [[k, dictsum[k][0]+max_non_values[k][0], dictsum[k][1]+max_non_values[k][1]] for k in dictsum]

由于您要进行求和,因此使用 defaultdict 比检查 dict 中的键更快、更简单;您还需要进行两次传递,或使用两个字典。另外,我建议将“示例”中的值设为一个类,或者至少是一个命名元组。将数据收集为非结构化整数和字符串的异构列表变得难以管理,超出几行代码即可。

【讨论】:

  • 我会考虑您的建议,毕竟有一个有序的程序以更快地解决问题很重要,非常感谢您的贡献,问候。 @kcsquared。
猜你喜欢
  • 2021-04-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-09
  • 1970-01-01
  • 1970-01-01
  • 2020-11-21
  • 1970-01-01
  • 2019-09-24
相关资源
最近更新 更多