【问题标题】:List with duplicated values and suffix具有重复值和后缀的列表
【发布时间】:2017-12-20 16:29:53
【问题描述】:

我有一个列表,a:

a = ['a','b','c']

并且需要复制一些以这种方式添加后缀_ind的值(顺序很重要):

['a', 'a_ind', 'b', 'b_ind', 'c', 'c_ind']

我试过了:

b = [[x, x + '_ind'] for x in a]
c = [item for sublist in b for item in sublist]
print (c)
['a', 'a_ind', 'b', 'b_ind', 'c', 'c_ind']

有没有更好、更 Pythonic 的解决方案?

【问题讨论】:

  • 郑重声明,这个解决方案没有任何问题。

标签: python list list-comprehension suffix


【解决方案1】:

你可以把它变成一个生成器:

def mygen(lst):
    for item in lst:
        yield item
        yield item + '_ind'

>>> a = ['a','b','c']
>>> list(mygen(a))
['a', 'a_ind', 'b', 'b_ind', 'c', 'c_ind']

您也可以使用 itertools.productitertools.starmapitertools.chain 或嵌套推导来实现,但在大多数情况下,我更喜欢简单易懂的自定义生成器函数。


使用python3.3,您还可以使用yield from——生成器委托——让这个优雅的解决方案更加简洁:

def mygen(lst):
    for item in lst:
        yield from (item, item + '_ind')

【讨论】:

  • 我可以建议一个列表理解版本吗? list([((yield x), (yield (x + '_ind'))) for x in a]) ; ['a', 'a_ind', 'b', 'b_ind', 'c', 'c_ind']
  • @cᴏʟᴅsᴘᴇᴇᴅ Wtf...从未见过这样的“内联”产量。再玩一些,这也有效:list([(yield from (x, x + '_ind')) for x in a]).
  • @StefanPochmann 杀手。想用它发布答案吗?如果没有,我会编辑我的。 :p
  • @StefanPochmann 这只是 py3k。他们添加了对列表组合的产量支持,以允许创建生成器。
  • @idjaw 哦,等等,刚刚在我的 IDE 上也看到了红色下划线。 xD
【解决方案2】:

可以通过将选项移动到列表推导中的内部 for 循环来缩短一点:

a = ['a','b','c']

[item for x in a for item in (x, x + '_ind')]
# ['a', 'a_ind', 'b', 'b_ind', 'c', 'c_ind']

【讨论】:

    【解决方案3】:

    另一种拼接方式(Python2.x、3.x):

    result = [None] * len(a) * 2
    result[::2], result[1::2] = a, map(lambda x: x + '_ind', a)
    
    result
    # ['a', 'a_ind', 'b', 'b_ind', 'c', 'c_ind']
    

    【讨论】:

    • "仅限 Python 3.x" - 实际上它只是 Python 3.3 及更高版本。见here
    • @ChristianDean 谢谢。添加链接。
    • @Bergi 是的,因为带有 yield 的列表 comp 返回一个生成器。
    • 如果你想混淆你的 Python 代码,这个选项最有用。
    • @cᴏʟᴅsᴘᴇᴇᴅ 不,密码高尔夫 Psidom 的答案获胜。 :)
    【解决方案4】:

    你可以使用itertools.chain():

    import itertools
    
    l = ['a','b','c']
    
    new_list = list(itertools.chain.from_iterable([[i, i+"_ind"] for i in l]))
    
    print new_list
    

    输出:

    ['a', 'a_ind', 'b', 'b_ind', 'c', 'c_ind']
    

    【讨论】:

    • 我会使用chain.from_iterable。这样你就不需要用*解包了
    • Alt:list(itertools.chain(*zip(a, [x + '_ind' for x in a])) )list(itertools.chain(*zip(a, map(lambda x: x + '_ind', a))))
    • @cᴏʟᴅsᴘᴇᴇᴅ 同意,但同样,chain.from_iterable 恕我直言会更干净:) list(chain.from_iterable(zip(a, [i+'_ind' for i in a])))。并不是说它特别重要。
    【解决方案5】:

    在列表推导和生成器被发明/普及之前,人们过去的想法要简单得多1

    >>> a = ['a', 'b', 'c']
    >>> b = []
    >>> for x in a: b.extend([x, x+'_ind'])
    ... 
    >>> b
    ['a', 'a_ind', 'b', 'b_ind', 'c', 'c_ind']
    

    * 我并不是说那些构造/工具是邪恶的,只是想指出有一个简单的解决方案。

    【讨论】:

    • 据我所知,发明(实现)理解和生成器是为了使这些“构造和工具”更简单(而且肯定更快)。但我想这是一个非常基于意见的陈述,所以 YMMV。
    【解决方案6】:

    既然你要求“简单”,我想我会把它扔进去(尽管可能不是pythonic 方式):

    for i in mylist: 
        mylist1.append(i);
        mylist1.append(i + '_ind');
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-04
      • 2017-12-02
      • 1970-01-01
      • 1970-01-01
      • 2018-08-23
      • 2023-03-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多