【问题标题】:Split a python list into other "sublists" i.e smaller lists [duplicate]将python列表拆分为其他“子列表”,即较小的列表[重复]
【发布时间】:2012-03-29 02:20:50
【问题描述】:

我有一个运行到 1000 个的 python 列表。比如:

data=["I","am","a","python","programmer".....]

其中,len(data)= 说 1003

我现在想通过将原始列表分成 100 个块来创建此列表(数据)的子集。所以,最后,我希望有类似的东西:

data_chunk1=[.....] #first 100 items of list data
data_chunk2=[.....] #second 100 items of list data
.
.
.
data_chunk11=[.....] # remainder of the entries,& its len <=100, len(data_chunk_11)=3

有没有pythonic方法来完成这个任务?显然我可以使用 data[0:100] 等等,但我假设这是非常非 Pythonic 并且非常低效。

非常感谢。

【问题讨论】:

  • 您可以使用numpy's array_split function 例如np.array_split(np.array(data), 20) 分割成20 个几乎相等大小的块。为确保块大小完全相同,请使用np.split。

标签: python python-2.7


【解决方案1】:

我会说

chunks = [data[x:x+100] for x in range(0, len(data), 100)]

如果你使用python 2.x而不是3.x,你可以通过使用xrange()来提高内存效率,将上面的代码更改为:

chunks = [data[x:x+100] for x in xrange(0, len(data), 100)]

【讨论】:

  • 我也愿意。您也许可以使用 itertools 以更“pythonic 的方式”来完成它,但它会像罪恶一样丑陋!
  • 如果您有一个列表并想要一个列表,那么没有理由为 itertools 烦恼。只有在您想拆分数据流而不创建整个数据流时,它们才有意义。
  • 使用 itertools 实际上是不那么 Pythonic 的方式,不是吗?
【解决方案2】:
chunks = [data[100*i:100*(i+1)] for i in range(len(data)/100 + 1)]

这相当于接受的答案。例如,为了便于阅读,将批次缩短为 10 个:

data = range(35)
print [data[x:x+10] for x in xrange(0, len(data), 10)]
print [data[10*i:10*(i+1)] for i in range(len(data)/10 + 1)]

输出:

[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [10, 11, 12, 13, 14, 15, 16, 17, 18, 19], [20, 21, 22, 23, 24, 25, 26, 27, 28, 29], [30, 31, 32, 33, 34]]
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [10, 11, 12, 13, 14, 15, 16, 17, 18, 19], [20, 21, 22, 23, 24, 25, 26, 27, 28, 29], [30, 31, 32, 33, 34]]

【讨论】:

  • 问的不是这个。
  • 其实是等价的,除了最后一批丢失的bug,现已修复。
  • 如果你的数据不能被 10 整除怎么办?
  • @AARon 没关系。最后一个列表会更小
【解决方案3】:

其实我认为在这种情况下使用普通切片是最好的解决方案:

for i in range(0, len(data), 100):
    chunk = data[i:i + 100]
    ...

如果您想避免复制切片,可以使用itertools.islice(),但这里似乎没有必要。

itertools() 文档还包含著名的“grouper”模式:

def grouper(n, iterable, fillvalue=None):
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

您需要对其进行修改以正确处理最后一个块,因此我认为使用普通切片的直接解决方案更可取。

【讨论】:

  • 感谢您的回复。我确实想到了你的第一个普通切片解决方案,但后来认为它可能效率太低而且我太天真了。我有点惊讶没有一种 Python 方式(一个衬垫)来完成这项任务:(
猜你喜欢
  • 1970-01-01
  • 2021-02-02
  • 1970-01-01
  • 2020-05-05
  • 1970-01-01
  • 1970-01-01
  • 2012-07-12
  • 2018-05-26
  • 2012-11-04
相关资源
最近更新 更多