【问题标题】:How to change list values in dictionary in python?如何在python中更改字典中的列表值?
【发布时间】:2017-10-31 04:47:07
【问题描述】:

我有一本这样的字典,

{'A':[[1,30],[40,50],[60,79]]
 'B':[[2,23],[26,43],[59,119]]
 'C':[[1,100],[149,167],[199,250]]
  ...                             }

我的 MAX 值为 600。是否可以计算每个列表中每个值之间的差异? 终于可以得到这样的字典了

 {'A':[[31,39],[51,59],[80,600]]
     'B':[[24,25],[44,58],[120,600]]
     'C':[[101,148],[168,198],[251,600]]
      ...                             
                                     }

让我解释一下最终输出是如何产生的。 原始数据是

'A':[[i1,i2],[i3,i4],[i5,i6]]

最大值为M,

对于每个列表,最终输出将是这样的

'A':[[(i2)+1,(i3)-1],[(i4)+1,(i5)-1],[(i6)+1,M]]

看来我需要一个 for 循环才能到达那里。但我不知道如何在字典中做到这一点。

【问题讨论】:

  • 你究竟是如何从 orinal 得到期望值的?
  • 我不确定您所说的“计算每个列表中每个值之间的差异”是什么意思。我似乎无法做任何接近此的事情,并获得您的预期输出。
  • 嗨@KlausD。 @trueCamelType 我更新了底部的问题。
  • 字典的每个值是否正好包含 3 个内部列表?

标签: python numpy dictionary calculation


【解决方案1】:

你可以试试这个:

d1 = {'A':[[1,30],[40,50],[60,79]],
      'B':[[2,23],[26,43],[59,119]],
      'C':[[1,100],[149,167],[199,250]]}

def split_l(iterable, n):
    return [iterable[i:i+n] for i in range(0, len(iterable), n)] 

d2 = {k:split_l([val + (-1)**idx for idx, val in enumerate(sum(v, [])[1:])] + [600], 2) for k,v in d1.items()} 

或者以更易读的方式:

d2 = {}
for k, v in d1.items():
    flat_v = sum(v, [])[1:]

    for idx, __ in enumerate(flat_v):
        flat_v[idx] += (-1)**idx
    flat_v.append(600)

    split_v = [flat_v[i:i+2] for i in range(0, len(flat_v), 2)]
    d2[k] = split_v

结果:

import pprint
pprint.pprint(d2)
{'A': [[31, 39], [51, 59], [80, 600]],
 'B': [[24, 25], [44, 58], [120, 600]],
 'C': [[101, 148], [168, 198], [251, 600]]}

【讨论】:

    【解决方案2】:

    你可以itertools.chain

    >>> from itertools import chain
    >>> d = {'A':[[1,30],[40,50],[60,79]], 'B':[[2,23],[26,43],[59,119]],}
    >>> for key in d:
    ...     d[key] = zip(*[iter([each+((-1)**index) for index,each in enumerate(chain.from_iterable(d[key]))]+[600,])]*2)
    ...
    >>> d
    {'A': [(31, 39), (51, 59), (80, 600)], 'B': [(24, 25), (44, 58), (120, 600)]}
    

    也就是说,

    >>> chain.from_iterable(d['A'])
    <itertools.chain object at 0x7f6a9dd69950>
    >>> list(chain.from_iterable(d['A']))
    [31, 39, 51, 59, 80, 600]
    
    >>> iter(each for each in enumerate(chain.from_iterable(d[key])))
    <generator object <genexpr> at 0x7f6a9dd804b0>
    >>> zip(*[iter(each for each in enumerate(chain.from_iterable(d[key])))]*2)
    [((0, 2), (1, 23)), ((2, 26), (3, 43)), ((4, 59), (5, 119))]
    

    【讨论】:

      【解决方案3】:

      请记住,在 python 中,您可以通过这种方式交换两个变量的值:

      a, b = b, a
      

      所以你的问题可以这样解决:

      def my_func(a_dict, max):
          for row in a_dict.values():
              row[0][0], row[0][1], row[1][0], row[1][1], row[2][0], row[2][1] = \
              row[0][1]+1, row[1][0]-1, row[1][1]+1, row[2][0]-1, row[2][1]+1, max
      

      需要注意的一点是没有return ...
      字典 是可变的,因此对a_dict 的任何更改都将保留。
      调用my_func 后,传递给函数的字典将包含结果。


      更新
      @MaximTitarenko 告诉我,每行中的内部列表数量(行=与字典键关联的列表)可能会有所不同。 所以我写了另一个在这种情况下工作的脚本:

      def make_result(a_dict, max):
          for row in a_dict.values():
              for index in range(len(row)-1):
                  row[index][0] = row[index][1] + 1
                  row[index][1] = row[index+1][0] -1
              row[-1][0] = row[-1][1] + 1
              row[-1][1] = max
      

      【讨论】:

      • 如果每行有500个元素怎么办?
      • @MaximTitarenko format of rows 在问题中被提及,它包含三个内部列表:[[(i2)+1,(i3)-1],[(i4)+1,(i5)-1],[(i6)+1,M]]
      • 每行 3 个元素只是一个例子。更重要的是问题本身及其在一般情况下的解决方案
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-08
      • 2019-03-29
      相关资源
      最近更新 更多