【问题标题】:Python list of tuples with variable length: Get string representation of tuples holding only object attributes具有可变长度的元组的 Python 列表:获取仅包含对象属性的元组的字符串表示
【发布时间】:2018-02-27 23:50:15
【问题描述】:

我有一个由某个类的对象组成的元组列表,它们的维度不同:

my_list = [(obj1, obj2), (obj3, obj1), (obj4, obj1), (obj2,),...]

所有这些对象都有一个属性label,它的类型是string,并拥有一个对象标签,例如'object_1''object_2' 等等。

现在我想提取包含属性值(标签)的元组的字符串表示,例如:

my_new_list = ['(object_1, object_2)', '(object_3, object_1)', '(object_4, object_1)', '(object_2,)', ...]

我已经查找了如何从对象列表中查找extract a list of attributes 以及如何查找convert a tuple to string,并且可能会通过一些嵌套的 for 循环来实现我的目标。但是我在这里遇到了一些乱七八糟的代码..

但是没有一些不错的pythonic方法可以做到这一点吗?

提前致谢!

*编辑:一些元组是一维的,例如(obj2,)。抱歉,我忘记了,现在修改了我的问题!

【问题讨论】:

  • 这里的标准列表理解有什么问题?
  • 不仅仅是对象,而是元组字符串表示中的属性。
  • 作为一般提示,您通常可以通过用实际的 for 循环写出理解的结构来查看它。在这种情况下,您将编写 for obj1, obj2 in my_list 以显示元组,然后将 '(%s,%s)' % (obj1.label, obj2.label) 附加到最初为空的列表中。您可以在下面的答案中看到相同的结构。编辑:刚刚看到编辑。同样的一般原则也适用。
  • 感谢您的提示!
  • 我添加了一个更通用的答案,不使用我认为很好读并且是标准 python 的嵌套推导。使用__repr__ 函数为您的类提供良好的字符串表示是一种很好的做法,这样它们就可以以这样的方式使用。 print(my_obj) 只是比 print(my_obj.label) 更好,如果标签是有意义的......好吧......对象的标签。

标签: python list tuples


【解决方案1】:

元组列表元素计数 使用 len() + 生成器表达式

temp = list((int(j) for i in test_list for j in i)) 
res = len(temp)

【讨论】:

    【解决方案2】:

    您可以使用map 函数来提供帮助。这可以在一行代码中完成

    my_new_list = list(map(lambda P: '({})'.format(','.join(list(map(lambda t:t.label,list(P))))),my_list))

    这也适用于一维元组。

    【讨论】:

      【解决方案3】:

      另外两个简单的列表理解答案适用于具有该属性的对象元组的任意列表。但是,Python 有一些很棒的内置功能,可以让您选择对象的字符串表示形式,并且大多数内置类型已经有了这个功能。例如,任何tuple 都可以通过用str(tuple) 封装tuple 来转换为它的字符串表示:

      >>> str((5, 4))
      '(5, 4)'
      

      现在,如果您对任意对象的元组执行此操作,那么您将得到一个字符串,该字符串具有像 <__main__.YourClass object at 0x10ad58fd0> 这样的实际对象句柄,这很难看。但是,如果您在类定义中提供 __repr__ 函数,那么您可以将该标准句柄更改为您喜欢的东西。在这种情况下,您的 label 似乎是返回对象的字符串表示的不错选择。这是使用相同代码创建的最小示例:

      class LabeledObj:
      
          def __init__(self, label):
              self.label = label
      
          def __repr__(self):
              return self.label
      
      
      obj1 = LabeledObj('object_1')
      obj2 = LabeledObj('object_2')
      obj3 = LabeledObj('object_3')
      obj4 = LabeledObj('object_4')
      
      my_list = [(obj1, obj2), (obj3, obj1), (obj4, obj1), (obj2,)]
      
      my_new_list = [str(obj_tuple) for obj_tuple in my_list]
      print(my_new_list)
      

      ['(object_1, object_2)', '(object_3, object_1)', '(object_4, object_1)', '(object_2,)']

      现在我认为 this 在后面的代码中非常 Python 和非常清晰,定义 __repr__ 只需要额外的两行代码。现在你可以用print(my_obj) 代替print(my_obj.label) 了。

      【讨论】:

      • 我想这是最干净的解决方案。谢谢大家!
      【解决方案4】:

      您可以为此使用list comprehension

      ['({}, {})'.format(el1.label, el2.label) for el1, el2 in my_list]
      

      不依赖元组维度使用辅助函数:

      def tuple_print(tup):
          return '({})'.format(', '.join(t.label for t in tup))
      
      my_new_list = [tuple_print(tup) for tup in my_list]
      

      【讨论】:

      • 感谢您的回答,看起来也不错。不幸的是,我忘了提到元组的维度不同..
      • 编辑我的答案。请注意,我使用 python3
      【解决方案5】:

      你可以的

      ["(%s, %s)" %(i.label, j.label) for i, j in my_list]
      

      如果元组内部是动态长度:

      ["(%s)" %", ".join([j.label for j in i]) for i in my_list]
      

      【讨论】:

      • 感谢您的回答。这是一个非常好的解决方案。不幸的是,我忘记了一个细节:元组有时是一维的,例如(obj1,)。我会调整我的问题。对不起!
      • @CordKaldemeyer 编辑了答案
      • 像魅力一样工作!你拯救了我的一天。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-07
      相关资源
      最近更新 更多