【问题标题】:Fast subset sublists in PythonPython中的快速子集子列表
【发布时间】:2017-02-20 09:33:12
【问题描述】:

我有一个包含数千条记录的子列表。 列表中的一个示例如下:

list_full = [
    [343, 354,"Sometext1", "Sometext2", "Sometext3"],
    [43543, 345435,"Sometext1", "Sometext2", "Sometext3"],
    [4354, 54354,"Sometext1", "Sometext2", "Sometext3",
         "Sometext4", "Sometext5"]
]

我想将此主列表分成两个单独的列表。第一个列表应该有来自子列表的前两条记录,第二个应该有剩余的记录。 例如,我需要将它们存储为:

list_a = [[343, 354], [43543, 345435], [004354, 54354]]
list_b = [["Sometext1", "Sometext2", "Sometext3"], ["Sometext1", "Sometext2", "Sometext3"], ["Sometext2", "Sometext3", "Sometext4", "Sometext5"]]

我有以下脚本:

list_1 = []
list_2 = []

for item in list_full:
    list_1.append(item[:2])
    list_2.append(item[2:])

但是使用循环并且有点慢。有没有更快的方法来执行这个列表子集?谢谢!

【问题讨论】:

  • 从您的问题陈述看来,您正在处理某种结构化数据。我建议看一下 pandas 库,因为从长远来看,它似乎是一个潜在的迭代库。它将允许您执行切片、索引和更多功能。
  • 我认为您当前的方法很好,其他可能的方法(例如列表推导或 map)将需要迭代 list_full 两次而不是一次
  • 感谢您的提示。不过,列表理解似乎更快。

标签: python list loops subset


【解决方案1】:

我会懒惰地用itertools

import itertools

list1 = itertools.imap(lambda x: itertools.islice(x, 0, 2), list_full)
list1 = itertools.imap(lambda x: itertools.islice(x, 2, None), list_full)

这样,在您需要之前不会评估计算。请注意,如果您希望立即对其进行评估,您可以调用 list() 将 itertools 对象转换为列表。

【讨论】:

  • 感谢您的回答。在一小部分数据上,我发现列表理解更快。
  • @Litwos,是的,对于小数据,itertools 可能会更慢,但是当你有大量数据时考虑一下 :)
  • 我在更大的子集上再次进行了测试,它比列表理解更快。谢谢
【解决方案2】:

试试这个:

# to create two lists
list_1 = [x[:2] for x in list_full]
list_2 = [x[2:] for x in list_full]

# to create two generators, supporting iteration (with for) but not indexing
list_1 = (x[:2] for x in list_full)
list_2 = (x[2:] for x in list_full)

或者,在 python 3 中,无需创建列表即可轻松迭代数据:

for a, b, *other in list_full:
    print("first:", a, b)
    print("other:", other)

【讨论】:

  • 我不能使用生成器,因为我需要索引。列表理解是数据子集上最快的。谢谢!
【解决方案3】:

您可以尝试列表理解,

list_1=[item[:2] for item in list_full]
list_2 = [item[2:] for item in list_full]

基于一些documents 列表理解比循环快得多。

您可以使用timeit 计算这两种方法所花费的时间,

from timeit import default_timer as timer
start=timer()
list_1 = []
list_2 = []

for item in list_full:
    list_1.append(item[:2])
    list_2.append(item[2:])

print list_1
print list_2

end=timer()

print end-start #Takes 0.0002339

在使用列表推导时,

from timeit import default_timer as timer
start = timer()
list_1=[item[:2] for item in list_full]
list_2 = [item[2:] for item in list_full]

print list_1
print list_2

end = timer()

print end-start #gives 0.0002105

【讨论】:

  • 我对一小部分数据进行了测试,你的答案是最快的。谢谢!
  • 我按照建议对更大的数据样本进行了测试,使用 itertools 被证明更快。我会记住对较小子集的列表理解! :)
猜你喜欢
  • 2013-06-05
  • 2019-04-15
  • 2012-12-08
  • 1970-01-01
  • 1970-01-01
  • 2013-07-03
  • 2014-09-04
  • 1970-01-01
  • 2018-02-11
相关资源
最近更新 更多