【问题标题】:Python converting a tuple (of strings) of unknown length into a list of stringsPython将未知长度的(字符串)元组转换为字符串列表
【发布时间】:2015-05-12 14:52:55
【问题描述】:

我有一个递归的字符串元组,如下所示:

('text', ('othertext', ('moretext', ('yetmoretext'))))

(它实际上是一个字符串元组的元组 - 它是递归构造的)

我想将它展平成一个字符串列表,其中 foo[1] 将包含“text”、foo[2]“othertext”等等。

如何在 Python 中做到这一点?

副本是关于列表的二维列表,但这里我处理的是递归元组。

【问题讨论】:

  • 看起来链接到的副本只处理二维列表...
  • 递归级别是否固定? ('yetmoretext') 也应该是 ('yetmoretext',)
  • 其实,不,'yetmoretext' 后面没有逗号。逗号分隔元组的元素,因此在最后一个元素之后没有。递归级别不固定,但输入相对较小。无论如何,我成功了,请参阅编辑。
  • 实际上,在 ('yetmoretext') 之后没有逗号,你所拥有的是一个字符串。逗号使它成为一个元组。试试看:type(('a string')) vs type(('a tuple',))
  • @MalcolmTucker:如上所述,最里面的元素不是没有尾随逗号的元组,它是一个字符串。这就是使您在下面的答案起作用的原因。

标签: python string tuples


【解决方案1】:

我自己找到了答案,我会在这里提供以供将来参考:

stringvar = []
while type(tuplevar) is tuple:
        stringvar.append(tuplevar[0])
        tuplevar=tuplevar[1]
stringvar.append(tuplevar)  # to get the last element. 

可能不是最干净/最短/最优雅的解决方案,但它很有效,而且看起来很“Pythonic”。

【讨论】:

  • 这绝对是个好办法。但是,请查看@LexyStardust 和我发布的答案。这两个答案都更通用,并且不仅仅适用于嵌套元组的单一用例。 Lexy 将适用于元组子类,例如namedtuple。我的将适用于任何可迭代类,例如列表或子类可迭代类的自定义类。话虽如此,+1 用于回答您自己的问题并发布答案。
【解决方案2】:

如果您对递归级别不会变得太糟糕感到高兴(并且您使用的是最新版本的 Python):

def unpack(obj):
    for x in obj:
        if isinstance(x, str):
            yield x
        elif isinstance(x, tuple):
            yield from unpack(x)
        else:
            raise TypeError

x = ('text', ('othertext', ('moretext', ('yetmoretext',))))
result = list(unpack(x))
print(result)

会给你:

['text', 'othertext', 'moretext', 'yetmoretext']

如果在下一个元组之前有超过 1 个字符串,或者如果元组中直接有元组,或者元组之后的字符串等,这也将起作用。如果需要,您也可以轻松修改它以与其他类型一起使用,我可能在谨慎方面犯了不必要的错误。

【讨论】:

    【解决方案3】:

    这就是我的处理方式。这与之前的答案非常相似,但是它在应用程序中更通用,因为它允许展平任何类型的迭代,除了字符串类型的对象(即列表和元组),它还允许展平列表非字符串对象。

    # Python 3.
    from collections import abc
    
    def flatten(obj):
        for o in obj:
            # Flatten any iterable class except for strings.
            if isinstance(o, abc.Iterable) and not isinstance(o, str):
                yield from flatten(o)
            else:
                yield o
    
    data = ('a', ('b', 'c'), [1, 2, (3, 4.0)], 'd')
    result = list(flatten(data))
    assert result == ['a', 'b', 'c', 1, 2, 3, 4.0, 'd']
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-18
      • 2011-05-16
      • 2014-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-03
      • 2021-12-01
      相关资源
      最近更新 更多