2016-11-13 64 views
0

我需要分析的字典对于包括两个给定数字之间的数(作为参数)值之间的值的密钥,并返回通过键搜索在字典具有两个数

字典前面那些值:

{'P':[("Eight",1460, 225.0, 200.0, "fresco","Netherlands"),("Six",1465,81.0, 127.1, "tempera", "Netherlands")], 
     'V':[("Four",1661, 148.0, 257.0,"oil paint", "Austria"),("Two",1630, 91.0, 77.0, "oil paint","USA")], 
     'K':[("Five",1922,63.8,48.1,"watercolor","USA"),("Seven",1950,61.0,61.0,"acrylic paint","USA"),("Two",1965,81.3,100.3,"oil paint","United Kingdom")], 
     'C':[("Ten",1496,365.0,389.0,"tempera","Italy")], 
     'U':[("Nine",1203,182.0, 957.0,"egg tempera","Italy"), ("Twelve",1200,76.2,101.6,"egg tempera","France")] 
     } 

函数应该只返回两个数之间的数字存在的值。因此,如果函数被调用between_two_values应该如果1464和1496之间寻找值返回此:

between_two_values(dictionary1(), 1464, 1496) 

{'P': [('Six', 1465, 81.0, 127.1, 'tempera',  
'Netherlands')], 'C': [('Ten', 1496, 365.0, 
389.0, 'tempera', 'Italy')]} 

如果键的值的一个不具备1464年至1496年之间的数字,它不应该返回一个值并且只有在该范围内具有数字的那些数字之前有其密钥。这就是为什么在上面的'P'的例子中,有1460的第一个值没有返回,因为它不在2个数字之间。如果第一个数字大一些,函数中的第一个数字应该总是小于第二个数字,然后它应该只返回一个空字典。

这是我想出的代码我不认为它是正确的,但它显示可以解决此功能的逻辑。我感谢我收到的任何帮助

def between_two_values(dictionary,start,end): 
    for x in dictionary: 
     if end < x < start in dictionary: 
      return dictionary(x) 
+0

你运行你的这个代码对词典吗?任何错误消息显示? –

+0

@melgart现在它说类型错误:无法订购的类型:int() n00bprogrammer22

+2

很酷,这很有用。它是说你正在试图比较苹果和橘子。好像你不确定你在between_two_values()函数中比较的是什么。你为什么不考虑在for循环之后在那里放入一些print()语句,这样你就可以看到你正在迭代的数据。请记住,Python字典有映射到值的键,你可以像这样访问字典:dictionary [x] –

回答

0

您正确的道路上。这是解决问题的一个解决方案。

为了清晰起见,我更好地格式化了数据。当它被压缩下来时,我并没有立即看到每个字典值被包裹在一个列表中。当然这是一种面向风格的改变,但风格有助于可读性。

请注意,我已经做了一些假设,例如每个字典值将是一个列表。例如,您没有值的密钥的边缘情况将表示为[]而不是None。我也推断了我认为期望的输出来自您给出的例子。最后,您可以考虑使用collections.defaultdict来简化存储匹配的位置。

除此之外,这段代码没什么特别。你当然可以更多地压缩它,或者使用类来进行语义学。说到语义,我建议你使用比我更好的变量名称:“数据”,“记录”和“值”是非常通用的,但我觉得他们帮助解释解决方案,而我没有洞察这些数据代表什么。

如果您使用Python 2中,考虑使用的dictionary.iteritems()代替dictionary.items()

数据

data = { 
    'P': [ 
     ('Eight', 1460, 225.0, 200.0, 'fresco', 'Netherlands'), 
     ('Six', 1465, 81.0, 127.1, 'tempera', 'Netherlands'), 
    ], 
    'V': [ 
     ('Four', 1661, 148.0, 257.0, 'oil paint', 'Austria'), 
     ('Two', 1630, 91.0, 77.0, 'oil paint', 'USA'), 
    ], 
    'K': [ 
     ('Five', 1922, 63.8, 48.1, 'watercolor', 'USA'), 
     ('Seven', 1950, 61.0, 61.0, 'acrylic paint', 'USA'), 
     ('Two', 1965, 81.3, 100.3, 'oil paint', 'United Kingdom'), 
    ], 
    'C': [ 
     ('Ten', 1496, 365.0, 389.0, 'tempera', 'Italy'), 
    ], 
    'U': [ 
     ('Nine', 1203, 182.0, 957.0, 'egg tempera', 'Italy'), 
     ('Twelve', 1200, 76.2, 101.6, 'egg tempera', 'France'), 
    ], 
} 

代码

def between_two_values(dictionary, start, end): 
    matches = {} 
    for key, record_list in dictionary.items(): 
     for record in record_list: 
      value = record[1] 
      if start < value < end: 
       if key in matches: 
        matches[key].append(record) 
       else: 
        matches[key] = [record] 
    return matches 

result = between_two_values(data, 1464, 1496) 
print(result) 

输出

{'P': [('Six', 1465, 81.0, 127.1, 'tempera', 'Netherlands')]} 
+0

你知道你可以写:'如果开始<值<结束:' – AChampion

+0

@AChampion更新以反映这一点。谢谢。 –

+0

谢谢有没有办法返回结果而不是打印它?它在打印时起作用,但当我改变它返回时ays返回外部函数 – n00bprogrammer22

0

可以使用dict理解,构建结果,例如:

>>> {k: [e for e in v if 1464 < e[1] < 1496] for k, v in dictionary.items()} 
{'C': [], 
'K': [], 
'P': [('Six', 1465, 81.0, 127.1, 'tempera', 'Netherlands')], 
'U': [], 
'V': []} 

然后就消除了空的结果:

def between_two_values(dictionary, start, end): 
    result = {k: [e for e in v if start < e[1] < end] for k, v in dictionary.items()} 
    return {k: v for k, v in result.items() if v} 
+0

不错,简洁。 –

+0

你可以结合使用这个技巧:'{k:f for k,v in dictionary.items()for f in([e for e in v如果start

+0

是的,明白你可以做到这一点,但是在简洁性,可理解性和性能之间有一个平衡点。考虑到OPs处理@ n00bprogrammer22,我错误地在更冗长的一面,希望它更容易访问:)。我可以使用'result'的元组生成器来避免字典构造,但我不是一个过早(在优化中)。 – AChampion