【问题标题】:Create a set from items in two lists从两个列表中的项目创建一个集合
【发布时间】:2014-12-16 11:30:36
【问题描述】:

我有以下代码:

ids = set()
for result in text_results:
    ids.add(str(result[5]))
for result in doc_results:
    ids.add(str(result[4]))

text_resultsdoc_results 都是列表,其中包含您可能已经猜到的其他列表作为项目。使用漂亮的 oneliner 而不是两个 for 循环,有没有更有效的方法来做到这一点?

【问题讨论】:

  • 您想要单线的动机是什么?我发现当前的代码完全可读。
  • 你的代码是好的。在所有情况下,一个班轮并不更好
  • @NPE 我并没有严格设置为单行,但将其缩短为两行对我来说似乎是合理的。

标签: python list set


【解决方案1】:

我可能会写:

ids = set(str(result[5]) for result in text_results)
ids.update(str(result[4]) for result in doc_results)

至于效率,如果你想榨取所有可能的性能,那么你首先需要一个真实的数据集,然后你可以尝试map(或Python 2中的itertools.imap)和operator.itemgetter之类的东西,看看什么更快。

如果你绝对必须有一个单线:

ids = set(itertools.chain((str(result[5]) for result in text_results), (str(result[4]) for result in doc_results)))

不过,如果您想要单行,也值得优化简洁性,以便您的单行可读,然后查看性能是否足够:

ids = set([str(x[5]) for x in text_results] + [str(x[4]) for x in doc_results]))

这“感觉”效率低下,因为它连接了两个列表,这不是必需的。但这并不意味着它对您的数据确实效率低下,因此值得将其包含在您的测试中。

【讨论】:

  • 我喜欢你的第一个解决方案。谢谢,看起来好多了。
【解决方案2】:

这一个班轮应该可以工作:

ids = set(map (lambda x: str(x[4]), doc_results) + map(lambda x: str(x[5]), text_results))

【讨论】:

  • 单线?确实。对原作的改进?我个人不太确定。
  • @NPE ,我认为从列表中创建集合可能比逐个添加要快:stackoverflow.com/questions/5835657/…
  • @ReutSharabani 创建列表的成本如何?
  • @AshwiniChaudhary - 我喜欢史蒂夫杰索普的回答。但是现在我想知道python如何在内部处理这个......你是对的,创建列表值得优化。
  • 有一个合理的担忧,即创建一个大小未知的setlist 可能比创建一个效率低,因为需要重新分配数据结构增长。如果 Python 2 的 mapset 都包含检查它们是否可以看到 doc_resultstext_results 的大小,并从一开始就分配正确的大小,那么这完全有可能比我的答案更快。
【解决方案3】:

这个(包裹的)一个衬垫应该可以工作:

ids = set([str(tr[5]) for tr in text_results] +
          [str(dr[4]) for dr in doc_results])

【讨论】:

    【解决方案4】:

    我想这是一种更 Pythonic 的方式:

    map(str,set([i[5] for i in text_results]+[i[4] for i in doc_results]))
    

    演示:

    >>> text_results = [[1,2,3,4,5,6,7,8,9],[1,2,3,4,56,6],[4,5,6,1,2,6,22],[1,2,3,4,5,7,8,9]]
    >>> doc_results = [[1,2,3,4,5,9,7,8,9],[1,2,3,4,56,3],[4,5,6,1,2,7,22],[1,2,3,4,5,7,7,9]]
    >>> map(str,set([i[5] for i in text_results]+[i[4] for i in doc_results]))
    ['56', '2', '5', '6', '7']
    

    【讨论】:

      【解决方案5】:

      这样做:

      ids = {str(i) for text, doc in zip(text_results, doc_results) for i in (text[5], doc[4])}
      

      这是假设结果类似于:

      text_results = [['t11', 't12', 't13', 't14', 't15', 't16'], ['t21', 't22', 't23', 't24', 't25', 't26']]
      doc_results = [['d11', 'd12', 'd13', 'd14', 'd15', 'd16'], ['d21', 'd22', 'd23', 'd24', 'd25', 'd26']]
      

      而你想要:

      ids = {'d15', 't26', 't16', 'd25'}
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-03
      • 2014-06-29
      • 2017-09-28
      • 2017-08-31
      相关资源
      最近更新 更多