【问题标题】:How to structure elements with multiple characteristics in Python如何在 Python 中构造具有多个特征的元素
【发布时间】:2019-07-13 05:39:00
【问题描述】:

如果我有一组元素(A、B、C、D...),它们都具有两个或多个特征(每个都有颜色、形状等...),我该如何制作结构,以便我可以轻松地询问所有绿色元素或所有圆形元素的列表?
我想过使用字典,但我不知道这是否是实现这一目标的最有效方法。我知道每个对象的每个特征的值永远不会改变。特征不多,但对象多。

这是一个集合的样子:

test = {'ob1': {'color': ['green'], 
                'shape': 'round'},
        'ob2': {'color': ['red'], 
                'shape': 'round'},
        'ob3': {'color': ['green', 'yellow'], 
                'shape': 'cubic'}
        }

如果我想获取所有绿色对象,我想要一种简单的方法来获取包含 [ob1, ob2] 的列表。但同时,我希望仍然能够轻松找到给定对象的属性(例如,我想知道 obj1 是什么颜色和形状)。

【问题讨论】:

  • 因为您没有提供任何输入和输出。我会假设仅根据您的陈述,更可取的结构可能是classdict。如果您可以提供输入、您尝试过什么以及预期的输出,那将会很有用。
  • 如果我们能看到您的代码,我们会说是否使用 dict 或 class 更好

标签: python arrays python-3.x dictionary


【解决方案1】:

您可以使用命名元组,这是一种高效的数据格式。

from collections import namedtuple

Element = namedtuple('Element', 'color size id name')

ELEMENTS_DB = {'e1':Element('green', 12, 34, 'jack'),
               'e2':Element('blue', 132, 334, 'dan'),
               'e3':Element('green', 142, 434, 'ben')}

# get green elements
green_elements = [e for e in ELEMENTS_DB.values() if e.color == 'green']
print(green_elements)
# get 'e3' 
print(ELEMENTS_DB['e3'])

输出:

[Element(color='green', size=12, id=34, name='jack'), Element(color='green', 
  size=142, id=434, name='ben')]
Element(color='green', size=142, id=434, name='ben')

【讨论】:

  • 这个方法看起来很棒,但是有没有办法知道给定元素的其他特征(例如,如果我们有 str 'jack',我们怎么知道 'jack' 是颜色:green, size:12 and id:34?)
  • 我不确定我是否明白你的问题。你能再解释一下吗?如果元素具有像“id”或“名称”这样的标识符,并且您希望能够从 ELEMENTS_DB 中获取单个元素,则必须使用 dict 并将标识符用作键。
  • 在我的示例字典中,如果我写test['ob1'],我会得到ob1的所有属性。如果我写test['ob1']['color'],我会更准确地得到它的颜色。例如,我可以用你制作的 ELEMENT_DB 做类似的事情吗?编辑:好的,谢谢。所以我必须同时使用字典和命名元组结构来做我想做的事?
  • 不,你不能因为 ELEMENTS_DB 没有密钥。当您调用 'test['ob1']' 时,您指向的是一个对象。您无法以这种方式找到所有“绿色”元素。所以你需要解释你想要调用什么样的查询。
  • namedtuple 效率更高,并为开发人员提供“强类型”(e['color'] vs e.color])
【解决方案2】:

我不确定您的数据是什么样的,因此很难提出建议,但这看起来像是 pandas 的工作。 Pandas 可以创建一个基本上类似于电子表格的数据框。导入数据后,您可以根据特征进行过滤和排序。不过,在大多数情况下,字典会很好。见pandas documentation

【讨论】:

    【解决方案3】:

    在我看来,Pandas 是一个很好的方法。但是你当然可以使用字典:

    elements = ['A', 'B', 'C', 'D']
    colors = ['red','red', 'blue', 'red']
    shapes = ['square', 'circle', 'circle', 'triangle']
    
    
    dict1 = { element: {'color':colors[index], 'shape':shapes[index]} for index,element in enumerate(elements)}
    
    
    def find_keys(keyword):
        result = []
        for key, val in dict1.items():
            for k, v in val.items():
                if v == keyword:
                    result.append(key)
        return result
    
    print (find_keys('red'))
    

    输出:

     print (find_keys('red'))
    ['A', 'B', 'D']
    
    print (find_keys('circle')) 
    ['B', 'C']
    

    【讨论】:

    • 我在想这个解决方案,但是如果dict1中有很多元素会不会需要很长时间?那么在这种情况下,熊猫是一种更有效的解决方案吗?
    • 很可能是因为它必须遍历每个键。就像我在解决方案中所说的那样,我可能只使用 pandas 并过滤列。只是提供了一个带有字典的解决方案来提供选项。
    【解决方案4】:

    通常问题会展示非工作代码,以帮助开始工作。

    做到这一点的一种方法是有一个字典,其键是特征,每个值都是另一个字典,其键是每个属性的可能值。它的值将是一组具有给定属性值的元素。

    所有绿色元素都将是

    elements['colour']['green']
    

    所有圆形元素都是

    elements['shape']['circle']
    

    通过使用集合操作,可以很容易地找到圆形的绿色对象,例如,使用

    elements['colour']['green'].intersection(elements['shape']['circle'])
    

    【讨论】:

      【解决方案5】:

      你可以使用类:

      class element:
          def __init__(self,shape,color):
              self.shape=shape
              self.color=color
      

      查询函数:

      def query(data,shape=None,color=None):
           if shape:
               data=[x for x in data if x.shape==shape]
           if color:
               data=[x for x in data if x.color==color]
           return data
      

      使用:

      red_circle=element("circle","red")
      red_square=element("square","red")
      blue_circle=element("circle","blue")
      blue_square=element("square","blue")
      
      data=[red_circle,red_square,blue_circle,blue_square]
      qdata=query(data,color="blue")
      
      for x in qdata:
          print("shape: {} - color: {}".format(x.shape,x.color))
      

      【讨论】:

      • 我考虑过这个解决方案,但有人告诉我,对于具有变化特征的对象,类更有效。由于我的集合将保持不变,我认为创建字典会更方便?
      • 问题可以有多种解决方案当然你可以用字典解决这个问题
      猜你喜欢
      • 2013-02-06
      • 1970-01-01
      • 1970-01-01
      • 2021-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多