【问题标题】:Insert element in Python list after every other element list comprehension在每个其他元素列表理解之后在 Python 列表中插入元素
【发布时间】:2021-06-27 03:39:08
【问题描述】:

目标是在列表中除最后一个元素之外的每个其他元素之后插入一个字符串:

arr0 = ['aa','bb','cc','dd']

目标

 ['aa','XX','bb', 'XX','cc','XX','dd']

这个话题已经在this 之类的帖子中得到解决,但是使用的字符串列表只有一个字符的长度,这会影响列表的理解。我没有足够的声望点来发表评论并要求澄清。

我已经使用 for 循环实现了它,但我正在尝试使用列表理解进行练习,并且希望了解我在哪里出错了。目前收到SyntaxError: invalid syntax

示例和当前实现

arr0 = ['aa','bb','cc','dd'] # Goal ['aa','XX','bb', 'XX','cc','XX','dd']

# Stop for range
total = len(arr0)*2-1

for i in range(1, total, 2):
   arr0.insert(i, "XX")

# Returns ['aa', 'XX', 'bb', 'XX', 'cc', 'XX', 'dd']

列表理解尝试:

[el for y in [[el, 'XX'] if idx != len(arr0)-1 else el for idx, el in enumerate(arr0)] for el in y if isinstance(y, list) else el]
分解
[[el, 'XX'] if idx != len(arr0)-1 else el for idx, el in enumerate(arr0)]

# Returns
# [['aa', 'XX'], ['bb', 'XX'], ['cc', 'XX'], 'dd']

在外部理解中,我试图将其作为单个字符串列表返回。我正在尝试使用isinstance 来检查元素是否为列表(最后一项是字符串),如果不是则仅返回字符串。

编辑

我非常感谢您的回复。我应该包括我确实遇到的这种替代情况,即我不希望在末尾的“Note”元素之后插入元素,在这种情况下我无法执行切片。是否可以使用 step 进行负索引?

# Alternative scenario
arr1 = ['aa','bb','cc','dd', 'Note']

# ['aa','XX,'bb','XX,'cc','XX,'dd','Note']

【问题讨论】:

    标签: python for-loop nested list-comprehension nested-loops


    【解决方案1】:

    您可以简单地使用嵌套列表推导并去除最后一个元素:

    >>> [e for i in arr0 for e in [i, "XX"]][:-1]
    ['aa', 'XX', 'bb', 'XX', 'cc', 'XX', 'dd']
    

    您还可以使用.split()/.join() 技巧(可能性能较差):

    >>> ",XX,".join(arr0).split(",")
    ['aa', 'XX', 'bb', 'XX', 'cc', 'XX', 'dd']
    

    更奇葩的方式是使用itertools.chain

    >>> from itertools import chain
    >>> list(chain.from_iterable(zip(arr0, ["XX"]*len(arr0))))[:-1]
    ['aa', 'XX', 'bb', 'XX', 'cc', 'XX', 'dd']
    

    编辑:对于稍后添加到问题的替代情况,可以对输入进行切片并手动将最后一个元素附加到输出:

    >>> arr1 = ['aa','bb','cc','dd', 'Note']
    >>> [e for i in arr1[:-1] for e in [i, "XX"]][:-1] + [arr1[-1]]
    ['aa', 'XX', 'bb', 'XX', 'cc', 'XX', 'dd', 'Note']
    

    【讨论】:

    • 如果你添加另一个导入 from itertools import zip_longest 它可能会更短 chain.from_iterable(zip_longest(arr0, [], fillvalue="XX"))
    • @frost-nzcr4 但它并不短。它仍然会在最后留下一个"XX",您需要删除它。
    • 这部分会缩短["XX"]*len(arr0),反正很好回答)
    • 啊,没错,它肯定会更干净,如果不是更短的话。愿意将其发布为替代答案吗?
    • @Selcuk 由于我编辑中的情况,我最初使用枚举来控制创建 [elem, 'XX'] 的次数。但切片绝对适用于其他场景。
    【解决方案2】:

    只是为了好玩,如果您想要列表理解本身中的所有逻辑,可以考虑另一种选择:

    from itertools import zip_longest
    
    initial_list = ['aa','bb','cc','dd'] # Goal ['aa','XX','bb', 'XX','cc','XX','dd']
    
    padded_list = [
        value
        for item in zip_longest(initial_list, ["XX"] * (len(initial_list) - 1))
        for value in item
        if value
    ]
    
    print(padded_list)
    

    输出:

    ['aa', 'XX', 'bb', 'XX', 'cc', 'XX', 'dd']
    

    【讨论】:

      猜你喜欢
      • 2020-07-09
      • 2015-09-11
      • 1970-01-01
      • 2017-01-15
      • 2012-09-21
      • 1970-01-01
      • 1970-01-01
      • 2018-12-08
      • 2020-01-16
      相关资源
      最近更新 更多