【问题标题】:Truncate dictionary list values截断字典列表值
【发布时间】:2016-06-28 13:30:00
【问题描述】:

我正在尝试在字典中查找匹配值的键。但要获得任何类型的有效匹配,我需要截断列表中的值。

我想将十分之一的位置截断(例如“2.21”到“2.2”)。

dict1 = {'red':[1.98,2.95,3.83],'blue':[2.21,3.23,4.2333],'orange':[3.14,4.1,5.22]}

dict2 = {'green':[3.11,4.12,5.2],'yellow':[2.2,3.2,4.2],'red':[5,2,6]}

matches = []
for key1 in dict1:
    for key2 in dict2:
        if dict1[key1] == dict2[key2]:
            matches.append((key1, key2))

print(matches)

我试图让 "green""orange" 以及 "blue""yellow" 匹配。但我不确定是否需要先解析每个值列表,进行更改,然后继续。如果我可以对比较本身进行更改,那将是理想的。

【问题讨论】:

    标签: python list dictionary truncate


    【解决方案1】:
    d = {'green': [3.11, 4.12, 5.2]}
    
    >>> map(int, d['green'])
    [3, 4, 5]
    

    您需要在比较之前将列表项映射为整数

    for key2 in dict2:
        if map(int, dict1[key1]) == map(int, dict2[key2]):
            matches.append((key1, key2))
    

    我假设你想四舍五入。如果要四舍五入到最接近的整数,请使用 round 而不是 int

    【讨论】:

      【解决方案2】:

      您可以在列表上使用zip 并比较值,但您应该设置一个容差tol,两个列表中的一对值将被视为相同:

      dict1 = {'red':[1.98,2.95,3.83],'blue':[2.21,3.23,4.2333],'orange':[3.14,4.1,5.22]}
      dict2 = {'green':[3.11,4.12,5.2],'yellow':[2.2,3.2,4.2],'red':[5,2,6]}
      
      matches = []
      tol = 0.1 # change the tolerance to make comparison more/less strict
      for k1 in dict1:
          for k2 in dict2:
              if len(dict1[k1]) != len(dict2[k2]):
                  continue
              if all(abs(i-j) < tol for i, j in zip(dict1[k1], dict2[k2])):
                  matches.append((k1, k2))
      
      print(matches)
      # [('blue', 'yellow'), ('orange', 'green')]
      

      如果您的列表长度始终相同,您可以删除不匹配长度被跳过的部分。

      【讨论】:

      • 我认为它需要是一个元组列表,这并不重要。
      • 是的,不用担心 :),顺便说一句,你的解决方案是伟大的!
      • @RoadRunner -- 我认为我的更简单。见下文
      • 是的,它是@joelgoldstick,我只是试图使解决方案最接近 OPs 问题。但是,是的,使用map() 将浮点数转换为整数绝对是一种更简单的方法。
      • @RoadRunner 地图和列表理解是一个豆荚中的两颗豌豆。有人喜欢,有人喜欢。欢呼
      【解决方案3】:

      如果您只关心截断而不是实际舍入,则可以将值转换为字符串并切掉多余的部分:

      for key1 in dict1:
          for key2 in dict2:
              # I'm pulling these values out so you can look at them:
              a = str(dict1[key1])
              b = str(dict1[key2])
              # find the decimal and slice it off
              if a[:a.index('.')] == b[:b.index('.')]:
                  matches.append((key1, key2))
      

      如果要实际取整,使用内置的round(float, digits)(https://docs.python.org/2/library/functions.html):

      for key1 in dict1:
          for key2 in dict2:
              if round(dict1[key1],0) == round(dict2[key2], 0):
                  matches.append((key1, key2))
      

      (另外,注意你的缩进!)

      【讨论】:

      • 谢谢!这就是为什么 joel 的 map() 答案是我发布的第一个用例的最佳方法,而 Moses 的答案符合“不四舍五入截断到 1 位小数”规范。不过,我认为这是已编辑的,或者我在第一次阅读问题时错过了它。
      【解决方案4】:

      您可以在循环之间添加一些列表推导来将浮点数转换为整数,如下所示:

      dict1 = {'red':[1.98,2.95,3.83],'blue':[2.21,3.23,4.2333],'orange':[3.14,4.1,5.22]}
      
      dict2 = {'green':[3.11,4.12,5.2],'yellow':[2.2,3.2,4.2],'red':[5,2,6]}
      
      matches = []
      for key1 in dict1:
          for key2 in dict2:
              dict1[key1] = [int(i) for i in dict1[key1]]
              dict2[key2] = [int(i) for i in dict2[key2]]
      
              if dict1[key1] == dict2[key2]:
                  matches.append((key1, key2))
      print(matches)
      

      输出:

      [('blue', 'yellow'), ('orange', 'green')]
      

      我希望这会有所帮助:)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-29
        • 1970-01-01
        • 1970-01-01
        • 2013-01-07
        • 2023-01-29
        相关资源
        最近更新 更多